无法反序列化 java.time.Instant
Cannot deserialize java.time.Instant
我有一个 RestEasyClient,它必须反序列化一个内部有 java.time.Instant
的对象。我尝试从 jsr310 注册新的 JavaTimeModule 但仍然出现错误:
ObjectMapper mapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
ResteasyClient client = new ResteasyClientBuilder()
.register(mapper)
.build();
ResteasyWebTarget target = client.target(UriBuilder.fromPath(SERVICE_URL + "/api"));
错误:
Can not construct instance of java.time.Instant: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
修改 Rest Server 以正确序列化 Instant 后 class(例如:"fromTime":1525681860)
新错误:
Can not construct instance of java.time.Instant: no double/Double-argument constructor/factory method to deserialize from Number value (1.52568186E9)
我设法模拟了这个:
ObjectMapper deserializer = new ObjectMapper()
.registerModule(new JavaTimeModule());
Instant probe = deserializer.readValue("1525681860", Instant.class);
System.out.println(probe);
如果我删除 "registerModule" 行,我会得到同样的错误。
因此,结论是RestEasyClient没有注册模块。我肯定做错了什么。
你可以定义一个 ContextResolver
for ObjectMapper
:
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperContextResolver() {
this.mapper = createObjectMapper();
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
private ObjectMapper createObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return mapper;
}
}
然后在您的客户端实例中注册解析器:
ResteasyClient client = new ResteasyClientBuilder()
.register(ObjectMapperContextResolver.class).build();
或者,您可以注册一个 JacksonJsonProvider
. This class is the basic implementation of JAX-RS abstractions (MessageBodyReader
and MessageBodyWriter
) 的实例,以便将 JSON 内容绑定到 Java 个对象和从 Java 个对象绑定。
您可以使用 constructor that accepts an ObjectMapper
实例。
我有一个 RestEasyClient,它必须反序列化一个内部有 java.time.Instant
的对象。我尝试从 jsr310 注册新的 JavaTimeModule 但仍然出现错误:
ObjectMapper mapper = new ObjectMapper()
.registerModule(new JavaTimeModule());
ResteasyClient client = new ResteasyClientBuilder()
.register(mapper)
.build();
ResteasyWebTarget target = client.target(UriBuilder.fromPath(SERVICE_URL + "/api"));
错误:
Can not construct instance of java.time.Instant: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
修改 Rest Server 以正确序列化 Instant 后 class(例如:"fromTime":1525681860)
新错误:
Can not construct instance of java.time.Instant: no double/Double-argument constructor/factory method to deserialize from Number value (1.52568186E9)
我设法模拟了这个:
ObjectMapper deserializer = new ObjectMapper()
.registerModule(new JavaTimeModule());
Instant probe = deserializer.readValue("1525681860", Instant.class);
System.out.println(probe);
如果我删除 "registerModule" 行,我会得到同样的错误。
因此,结论是RestEasyClient没有注册模块。我肯定做错了什么。
你可以定义一个 ContextResolver
for ObjectMapper
:
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperContextResolver() {
this.mapper = createObjectMapper();
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
private ObjectMapper createObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return mapper;
}
}
然后在您的客户端实例中注册解析器:
ResteasyClient client = new ResteasyClientBuilder()
.register(ObjectMapperContextResolver.class).build();
或者,您可以注册一个 JacksonJsonProvider
. This class is the basic implementation of JAX-RS abstractions (MessageBodyReader
and MessageBodyWriter
) 的实例,以便将 JSON 内容绑定到 Java 个对象和从 Java 个对象绑定。
您可以使用 constructor that accepts an ObjectMapper
实例。