--- title: Converters --- #When to use a Converter? When a parameter is received, we need to convert to an Object. VRaptor already have registered converters for all types define in `Java Language Specification`. If the type is primitive and parameter is `null`, the default value for the type will be returned. Example: if your type is an `int` and the value is `null`, the value `0` will be returned. For the non-primitive types the `null` value is returned if the parameter is `null` or empty. For example, if we receive the parameters: | client.id | 10 | | client.age | null | {: .content-table} for the class below: ~~~ #!java public class Client { private Long id; private int age; // getters and setters } ~~~ When inject the parameter data, VRaptor will call `LongConverter` for the field `id` and `PrimitiveIntConverter` for the field `age`. In this case `id` will receive value `10`, and `age` will receive value `0` because parameter is null. You can see a complete list with all available converters here. ##BigDecimal, Double and Float with localization Are supported using application locale. `Double` and `Float` supports both primitive and non-primitive types. ##Working with Date and Calendar `Calendar` and `Date` are supported using application locale. There are converters for the main Joda-time types: `DateTime`, `LocalDate`, `LocalDateTime` and `LocalTime` available using the [vraptor-jodatime](/en/docs/plugins/#joda-time) plugin. If you are using JDK 8, you can use the new `java.time` API available using [vraptor-java8](/en/docs/plugins#vraptor-java-8) plugin. ##If conversion fails When a conversion fails VRaptor will add the error message using localization. To see these messages you need to add the lines below in your resource bundle: ~~~ #!properties is_not_a_valid_number = {0} is not a valid number. is_not_a_valid_integer = {0} is not a valid integer. is_not_a_valid_character = {0} is not a valid character. is_not_a_valid_enum_value = {0} is not a valid option. is_not_a_valid_date = {0} is not a valid date. is_not_a_valid_boolean = {0} is not a valid boolean. Please use true/false, yes/no, y/n or on/off is_not_a_valid_time = {0} is not a valid time. is_not_a_valid_datetime = {0} is not a valid datetime. ~~~ ##Changing your Locale The converters uses the JVM's default locale. You can override the JVM locale adding these lines in your web.xml: ~~~ #!xml javax.servlet.jsp.jstl.fmt.locale en_US ~~~ Or you can start your application server or servlet container using the VM parameter: ~~~ -Duser.language=en -Duser.region=US ~~~ ##Creating your own converter All converters must implement VRaptor's Converter interface. The concrete class will define which type it is able to convert, and will be invoked with a request parameter, the target type and a resource bundle containing i18n messages, useful if you wish to raise a ConversionException in case of convertion errors. ~~~ #!java public interface Converter { T convert(String value, Class type); } ~~~ Also you must tell VRaptor (not the compiler) which type your converter is able to handle. You do that by annotating your converter class with @Convert: ~~~ #!java @Convert(Long.class) public class LongConverter implements Converter { // your code here } ~~~ Finally, don't forget to specify the scope of your converter, just like you do with any other resource in VRaptor. For example, if your converter doesn't need any user specific information, it can be registered as application scoped and only one instance of that converter will be created: ~~~ #!java @Convert(Long.class) @ApplicationScoped public class LongConverter implements Converter { // your code here } ~~~ In the following lines, you can see a `LongConverter` implementation, showing how simple it is to assemble all the information mentioned above: ~~~ #!java @Convert(Long.class) @ApplicationScoped public class LongConverter implements Converter { public Long convert(String value, Class type) { if (isNullOrEmpty(value)) { return null; } try { return Long.valueOf(value); } catch (NumberFormatException e) { throw new ConversionException(new ConversionMessage("is_not_a_valid_integer", value)); } } } ~~~ ##Setting nested properties In the previous examples, we learn how to convert a request parameter to an object. For example, a parameter `country` can converted to a object `Country`. But there are some cases that you want to only setting a nested property, like a country name. For this case, if you have a request parameter `country.name`, you can create the converter below to instantiate a new Country instance only with name setted. ~~~ #!java @Convert(Country.class) @ApplicationScoped public class CountryConverter implements Converter { public Country convert(String value, Class type) { Country country = new Country(); if (!isNullOrEmpty(value)) { country.setName(value) } return country; } } ~~~ ##Overriding core converters You can also overrise any existing converters. You only need extends the core converter, after to add `@Specializes` annotation and `@Convert` with the specialized type. Below you can see an example how to override a converter `BigDecimalConverter`: ~~~ #!java @Specializes @Convert(BigDecimal.class) public class CustomBigDecimalConverter extends BigDecimalConverter { @Override public BigDecimal convert(String value, Class type) { // your code here return super.convert(value, type); } } ~~~ You can use CDI's `@Specializes` always you desire to reuse the `superclasse` behavior, otherwise you can create an `@Alternative` with higher priority than VRaptor implementation, i.e: ~~~ #!java @Alternative @Priority(Interceptor.Priority.APPLICATION) @Convert(BigDecimal.class) public class CustomDecimalConverter implements Converter{ @Override public BigDecimal convert(String value, Class type) { return // your code here } } ~~~ All of VRaptor's `Converter`s have `LIBRARY_BEFORE` priority.