我使用Jersey和Jackson作为JSON提供者。我可以将ZonedDateTime
序列化为JSON,但是当我想要反序列化时,它会给出如下错误。
请您帮我说明完成反序列化工作所需的确切配置。
引起:com.fasterxml.jackson.databind.JsonMappingException:无法从字符串值实例化类型[simple type,class java.time.ZonedDateTime]的值(' 2016-01-21T21:00:00Z& #39);没有单字符串构造函数/工厂方法
我的映射器配置如下:
@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;
}
}
答案 0 :(得分: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;
}
}