Recently I was struggling with Java 8 LocalDate issue with Jackson. After searching through docs and forums, finally I got it working. SO here I am posting so it might some one else in future.
Issue: If your JAXRS application is consuming or producing LocalDate from Java 8, Jackson version 1 will not convert it automatically with its aotations in place. You need to write custom logic for that.
Error will be like
No suitable constructor found for type [simple type, class java.time.LocalDate]: can not instantiate from JSON object (need to add/enable type information?)
Note: Every object used here is from codehaus(jackson1), not from fasterxml(jackson2) except LocalDate and LocalDateTime
So If your Application is consuming LocalDate , simply implement ParamHandler and parse string to LocalDate like below>
MyCustomParamHandler implements Paramhandler<Localdate>{
LocalDate fromString(String jsonString){
retu LocalDate.parse(jsonString);
}
}
And you list it under providers in just like below providers
Now, if REST application is consuming LocalDate, you need to write logic to serialize and deserialize it. Most posts say registering JavaTimeModule will solve it but it did not work for me. I did it like below
public class MyObjectMapper extends ObjectMapper {
public MyObjectMapper() {
SimpleModule sm = new SimpleModule("SomeName", new Version(1,1,1,""));
sm.addSerializer(LocalDate.class, new JsonSerializer<LocalDate>() {
@Override
public void serialize(LocalDate value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
ToStringSerializer.instance.serialize(value, jgen, provider);
}
});
sm.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
@Override
public void serialize(LocalDateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
ToStringSerializer.instance.serialize(value, jgen, provider);
}
});
sm.addDeserializer(LocalDate.class, new JsonDeserializer<LocalDate>() {
@Override
public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
retu LocalDate.parse(jp.getText());
}
});
sm.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
retu LocalDateTime.parse(jp.getText());
}
});
registerModule(sm);
}
}
Server Side configuration:
<bean id="mapper" class="mymapperpkg.MyObjectMapper"/>
<jaxrs:server>
......
.....
<jaxrs:serviceBeans>....</jaxrs:serviceBeans>
......
......
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider">
<constructor-arg index="0" ref="mapper"/>
<constructor-arg index="1">
<util:constant static-field="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS"/>
</constructor-arg>
</bean> -->
</jaxrs:server>
Client side configarion
<bean id="mapper" class="mymapperpkg.MyObjectMapper"/>
<jaxrs:client id="deliveryItemClient"
serviceClass="servicepkg.YourRESTServiceClass"
useame="adadsad"
password="asdasdasd"
address="adresss to deployed service">
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider">
<constructor-arg index="0" ref="mapper"/>
<constructor-arg index="1">
<util:constant static-field="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS"/>
</constructor-arg>
</bean>
</jaxrs:providers>
</jaxrs:client>
Cheers!
