2

我有一个 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"));

错误:

无法构造 java.time.Instant 的实例:找不到合适的构造函数,无法从 Object 值反序列化(缺少默认构造函数或创建者,或者可能需要添加/启用类型信息?)

修改 Rest Server 以正确序列化 Instant 类后(例如:“fromTime”:1525681860)

新错误:

无法构造 java.time.Instant 的实例:没有从数字值反序列化的双/双参数构造函数/工厂方法 (1.52568186E9)

我设法模拟了这个:

    ObjectMapper deserializer = new ObjectMapper()
            .registerModule(new JavaTimeModule());

    Instant probe = deserializer.readValue("1525681860", Instant.class);
    System.out.println(probe);

如果我删除“registerModule”行,我会得到同样的错误。

因此,结论是 RestEasyClient 没有注册模块。我肯定做错了什么。

4

1 回答 1

3

你可以定义一个ContextResolverfor 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. 此类是将JSON 内容绑定到 Java 对象和从 Java 对象绑定到所需的 JAX-RS 抽象(MessageBodyReader和)的基本实现。MessageBodyWriter

您可以使用接受实例的构造函数。ObjectMapper

于 2018-05-07T11:13:49.740 回答