Search code examples
java-8ibm-cloudwebsphere-liberty

java8 time deserialization in Websphere Liberty


I'm having trouble with my Websphere Liberty installation/IBM Bluemix instance. I'm using the new java.time classes (e.g. LocalDateTime) but the deserialized version using the Jackson 2.8 mapper results in badly handable results (full object deserialization instead of timestamps). https://geowarin.github.io/jsr310-dates-with-jackson.html But how can I do the same in Liberty? e.g.: receive 2016-02-02T23:24:08.255+01:00 as the result in a deserialized JSON response

Thanks


Solution

  • The Liberty JAX-RS 2.0 feature includes Jackson to do basic serialization of Java Classes to JSON, but it doesn't expose any of the Jackson APIs.

    If you want to change Jackson's behaviour, you should bundle these libraries in your application so that Liberty uses the Jackson that you've provided, rather than the one it has internally:

    Then you can also include the Jackson JSR310 module to get your Java 8 times serialized as you want.

    However, according to the documentation on that page, you need to register the module with your object mapper.

    You want to call JacksonJsonProvider.setMapper() but this isn't straighforwards as usually this object gets instantiated automatically by Liberty and you never see it.

    Instead, you can create a ContextProvider to tell the Jackson JAX-RS provider what ObjectMapper to use when it gets instantiated by Liberty.

    Adapting the example from your link, you could write something like this:

    @Provider
    public class JSR310MapperProvider implements ContextResolver<ObjectMapper> {
    
        @Override
        public ObjectMapper getContext(Class<?> type) {
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new JavaTimeModule());
            mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
            return mapper;
        }
    }
    

    That should create a configured mapper which should then be used by Jackson to serialize your Java 8 time objects.


    Update: If you're overriding getClasses() in your Application class, then the JacksonJsonProvider and your JSR310MapperProvider won't be automatically discovered. You'll need to include both of these classes in the set you return from getClasses()