首页 文章

无法使用Jackson反序列化ZonedDateTime

提问于
浏览
1

我使用Jersey和Jackson作为JSON提供者 . 我能够将 ZonedDateTime 序列化为JSON,但是当我想要反序列化时,它给出了如下错误 .

能帮我告诉一下这个反序列化工作所需的确切配置吗?

引起:com.fasterxml.jackson.databind.JsonMappingException:无法从String值('2016-01-21T21:00:00Z')实例化类型[simple type,class java.time.ZonedDateTime]的值;没有单字符串构造函数/工厂方法

我的mapper配置如下:

@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;
    }  
}

1 回答

  • 1

    我发现了问题,实际上问题不是使用标准的jackson提供程序进行反序列化 . 在我的例子中,我使用Jersey客户端获取JSON,然后使用readEntity方法反序列化 .

    问题是,泽西客户端不知道jsr310模块,因此通过注册已添加jsr310的contextresolver解决了这个问题 . 所以简而言之,如果使用普通的jackson提供程序,则无需为 ZonedDateTime 的seralization和反序列化做任何事情 .

    以下是我在这里提到的参考代码,以便更清晰 .

    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;
        }  
    }
    

相关问题