简体   繁体   中英

Unable to deserialize ZonedDateTime using Jackson

I am using Jersey with Jackson as JSON provider. I am able to serialize ZonedDateTime to JSON but when I want to deserialize it gives me error as follows.

Could you please help me tell the exact configuration required to get this deserialization work.

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.ZonedDateTime] from String value ('2016-01-21T21:00:00Z'); no single-String constructor/factory method

My mapper configuration is as follows:

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {  
    private final ObjectMapper MAPPER;

    public ObjectMapperContextResolver() {
        MAPPER = new ObjectMapper();
        //This would add JSR310 (Datetime) support while converting date to JSON using JAXRS service
        MAPPER.registerModule(new JavaTimeModule());
        //Below line would disable use of timestamps (numbers), 
        //and instead use a [ISO-8601 ]-compliant notation, which gets output as something like: "1970-01-01T00:00:00.000+0000".
        MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return MAPPER;
    }  
}

I found the problem, actually issue was not with Deserialization using standard jackson provider. In my case, I was using Jersey client to get JSON and then deserialize using readEntity method.

Problem was that jersey client was not aware of the jsr310 module, so by registering the contextresolver where jsr310 has been added solved the issue. So in nutshell, you don't need to do anything for seralization and deserialization of ZonedDateTime if using normal jackson provider.

Below is the reference code which I am referring here, to get better clarity.

public class RESTClientImpl{

    /*
     * ***This is very important, JacksonJsonProvider is the implementation of
     * MessageBodyWriter/Reader which is required for "readEntity" method, 
     * else it would throw MessageBodyWriter/Reader not found exception
     * 
     * https://jersey.java.net/documentation/latest/message-body-workers.html#mbw.ex.client.mbr.reg
     *
     * Registering of ObjectMapperContextResolver is important as we have registered JSR310 module there and without registering this, 
     * Jersey client is not aware of JSR310 module, so it will not be able to de-serialize ZonedDateTime
     */
    private final Client client = ClientBuilder.newClient(new ClientConfig().register(LoggingFilter.class)).register(JacksonJsonProvider.class)
            .register(ObjectMapperContextResolver.class);

    public User get(URI uri) {
        WebTarget webTarget = client.target(uri);

        Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
        Response response = invocationBuilder.get();    
        User user = response.readEntity(User.class);
        return user;
    }
}


@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {  
    private final ObjectMapper MAPPER;

    public ObjectMapperContextResolver() {
        MAPPER = new ObjectMapper();
        //This would add JSR310 (Datetime) support while converting date to JSON using JAXRS service
        MAPPER.registerModule(new JavaTimeModule());
        //Below line would disable use of timestamps (numbers), 
        //and instead use a [ISO-8601 ]-compliant notation, which gets output as something like: "1970-01-01T00:00:00.000+0000".
        MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addDeserializer(Object.class, new ZonedDateTimeDeserializer());
        MAPPER.registerModule(simpleModule);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return MAPPER;
    }  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM