【问题标题】:Unable to deserialize ZonedDateTime using Jackson无法使用 Jackson 反序列化 ZonedDateTime
【发布时间】:2016-04-25 23:28:08
【问题描述】:

我正在使用带有 Jackson 的 Jersey 作为 JSON 提供程序。我可以将ZonedDateTime 序列化为 JSON,但是当我想反序列化时,它会给我如下错误。

能否请您帮我说出完成此反序列化工作所需的确切配置。

原因:com.fasterxml.jackson.databind.JsonMappingException:无法从字符串值('2016-01-21T21:00:00Z')实例化类型[简单类型,类 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;
    }  
}

【问题讨论】:

    标签: java jackson java-time


    【解决方案1】:

    我发现了问题,实际上问题不在于使用标准杰克逊提供程序进行反序列化。就我而言,我使用 Jersey 客户端获取 JSON,然后使用 readEntity 方法进行反序列化。

    问题是 jersey 客户端不知道 jsr310 模块,因此通过注册添加了 jsr310 的 contextresolver 解决了该问题。所以简而言之,如果使用普通的杰克逊提供者,你不需要对ZonedDateTime的序列化和反序列化做任何事情。

    下面是我在这里引用的参考代码,以便更清楚。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-26
      • 2022-12-12
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多