In a webservice call, I would like to return my objects with this JSON structure.
{
"date" : "30/06/2014",
"price" : {
"val" : "12.50",
"curr" : "EUR"
}
}
I'd like to map this JSON code to this Java structure (with joda-time and joda-money):
public class MyResponse {
LocalDate date;
Money price;
}
My webservice currently looks like this:
@javax.ws.rs.POST
@javax.ws.rs.Path("test")
@javax.ws.rs.Produces({MediaType.APPLICATION_JSON})
@javax.ws.rs.Consumes({MediaType.APPLICATION_JSON})
public MyResponse test(MyRequest request) {
MyResponse response = new MyResponse();
response.setDate(LocalDate.now());
response.setMoney(Money.parse("EUR 12.50"));
return response;
}
So my question is: where do I register a custom handler to format dates as I want as well as money representations?
If you are using Jackson (which should be the default for JBoss EAP 6) you can use custom JsonSerializers
For the LocalDate
:
public class DateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate date, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString(date.toString("dd/MM/yyyy"));
}
}
For the Money
:
public class MoneySerializer extends JsonSerializer<Money> {
@Override
public void serialize(Money money, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField("val", money.getAmount().toString());
jgen.writeStringField("curr", money.getCurrencyUnit().getCurrencyCode());
jgen.writeEndObject();
}
}
Both Serializers can be registered globally:
@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper> {
private ObjectMapper objectMapper;
public JacksonConfig() {
objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule("MyModule", new Version(1, 0, 0, null));
module.addSerializer(Money.class, new MoneySerializer());
module.addSerializer(LocalDate.class, new DateSerializer());
objectMapper.registerModule(module);
}
public ObjectMapper getContext(Class<?> objectType) {
return objectMapper;
}
}
For parsing JSON in this custom format you need to implement custom JsonDeserializers.
If you are using Jettison you can do the same thing with custom XmlAdapters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With