12

我正在使用 Jersey JAX-RS 客户端(2.0 版)。我知道它使用 Jackson ObjectMapper 来生成和解析 JSON。我想使用同一个对象为一些 java 类生成 JSON,以便我可以将它们写入日志。

我知道我可以创建一个新的 ObjectMapper 实例,但我更喜欢请求 Jersey Client 给我一个它正在使用的引用。我怎样才能做到这一点?Jersey 2.0 意识到了 Jackson,因为它首先包含一个用于配置 Jackson 功能的 JacksonFeature 类。

4

3 回答 3

21

我通过添加以下静态成员解决了这个问题:

private static JacksonJsonProvider jackson_json_provider = new JacksonJaxbJsonProvider()
      .configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
      .configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

private static ObjectMapper object_mapper = jackson_json_provider.locateMapper(
      Object.class, MediaType.APPLICATION_JSON_TYPE);

private static Client client = ClientBuilder.newClient().register(jackson_json_provider);

请注意,第二个声明不仅仅需要配置FAIL_ON_UNKNOWN_PROPERTIESor FAIL_ON_EMPTY_BEANS; 我使用object_mapper其他一些原因。

于 2013-05-05T23:39:08.427 回答
17

Jersey 实际上并没有显式配置 ObjectMapper 实例,而是委托给JacksonJsonProvider,而后者又使用默认映射器实例。您可以跟踪JacksonProviderProxy 代码以查看它是如何工作的。您可以通过定义上下文解析器来创建和自定义要在整个应用程序中使用的共享映射器:

@Provider
public class ObjectMapperContextResolver implements
        ContextResolver<ObjectMapper> {
    private ObjectMapper mapper = null;

    public ObjectMapperContextResolver() {
        super();

        // Illustrate configuration of the mapper instance
        mapper = new ObjectMapper().configure(
                SerializationConfig.Feature.WRAP_ROOT_VALUE, true).configure(
                DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }
}

Jackson 提供程序将从该解析器中检索其映射器实例,您可以在代码中执行相同操作,如下所示:

public class MyResource {
    @Context
    private ContextResolver<ObjectMapper> mapperResolver;

    public void someResourceMethod() {
        final ObjectMapper mapper = mapperResolver.getContext(Object.class);
    }
}
于 2013-05-05T12:48:30.463 回答
1

基于此处的其他解决方案(使用jackson 2.8.3),无法使用球衣对象映射器对其进行配置。(我怀疑它可能与 osgi 容器有关,但尽管如此......)解决它的一种蛮力方法是从客户端获取 Response 对象并在其上调用您自己的 ObjectMapper 实例。然后,同样的实例也可以在其他地方与您的显式配置一起重用。

Client client = ClientBuilder.newClient();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
...
Response r = client.target(URL).request().get();
MyDtoClass dto = mapper.readValue((InputStream)(r.getEntity()), MyDtoClass.class);
于 2018-01-11T19:52:21.730 回答