users@jersey.java.net

[Jersey] Re: Date serialization format

From: Sadokhin, Vasiliy <vasiliy_at_lionhearth.com>
Date: Sun, 20 Nov 2011 12:15:24 +0900

Hello

maybe it helps:
> http://stackoverflow.com/questions/1465946/java-jaxb-and-using-char

Leonardo, I use JAXB and XmlAdapter implementation. It works great when
client requests something with response MediaType.APPLICATION_XML. But when
client requests JSON answer XmlAdapter will not work, Jersey
uses JacksonJsonProvider and ObjectMappers inside.

Just configure ObjectMapper with the date format you want:
> objectMapper.setDateFormat(new SimpleDateFormat(...));
> and that's it. Assuming you use POJO mapping.

Tatu, how do I let Jersey know to use my configured ObjectMapper?
I tried several cases. One of them is extending from JacksonJsonProvider:

@Provider
@Consumes({MediaType.APPLICATION_JSON, "text/json"})
@Produces({MediaType.APPLICATION_JSON, "text/json"})
public class OurJacksonJsonProvider extends JacksonJsonProvider {

    @Override
    public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) {
        ObjectMapper om = super.locateMapper(type, mediaType);
        SimpleDateFormat df = new SimpleDateFormat("yyyy");
        om.getSerializationConfig().setDateFormat(df);
        om.getDeserializationConfig().setDateFormat(df);
        return om;
    }
}


In this case JSON date parsing works great for responses. But POST requests
JSON parameters deserialization stops working for all application. I didn't
catch why. If I remove this class from the application deserialization will
work well. If I just remove locateMapper method it will not work.

Another way I tried that is create and register your own object mapper like
below (take a look both commented and not cases):

@Provider
@Produces("application/json")
public class JacksonConfigurator implements ContextResolver<ObjectMapper> {
    private ObjectMapper mapper = new ObjectMapper();
    public JacksonConfigurator() {
// ObjectMapper mapper = new ObjectMapper();
// mapper.getSerializationConfig().setDateFormat(new
SimpleDateFormat(DATE_FORMAT));
// mapper.getDeserializationConfig().setDateFormat(new
SimpleDateFormat(DATE_FORMAT));
//
 mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,
false);
// SimpleModule sm = new SimpleModule(Date.class.getName(), new
// Version(1, 0, 0, null)).addSerializer(Date.class, new
JsonDateSerializer());
// mapper.registerModule(sm);

        SerializationConfig serConfig = mapper.getSerializationConfig();
        serConfig.setDateFormat(new SimpleDateFormat(DATE_FORMAT));
        DeserializationConfig deserializationConfig =
mapper.getDeserializationConfig();
        deserializationConfig.setDateFormat(new
SimpleDateFormat(DATE_FORMAT));

mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS,
false);
    }
    @Override
    public ObjectMapper getContext(Class<?> arg0) {
        return mapper;
    }
}

I saw that Jersey creates my JacksonConfigurator but never calls getContext
method. I tried both examples with
disabled/enabled com.sun.jersey.api.json.POJOMappingFeature property in
web.xml. It didn't help, Jersey(Jacksone?) used their own ObjectMapper for
serialization/deserialization. I catched it using debug.
It looks like that I missed something simple and important related to
Jersey configuration. Any ideas?

I also tried one more approach:
http://blog.seyfi.net/2010/03/how-to-control-date-formatting-when.html
But my DateSerializer was not called at all. I saw old Jersey forum
discussion about it. Person recommended to enable POJO mapping. I did it
but DateSerializer was not called anyway. Where is a mistake?

Thanks,
Vasiliy