无法反序列化 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 实例。