【问题标题】:How to extract ObjectMapper from JAX-RS Client?如何从 JAX-RS 客户端中提取 ObjectMapper?
【发布时间】:2013-04-29 02:32:19
【问题描述】:

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

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

【问题讨论】:

    标签: json jersey jackson jax-rs jersey-client


    【解决方案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);
    

    【讨论】:

      【解决方案2】:

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

      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_PROPERTIESFAIL_ON_EMPTY_BEANS 不需要第二个声明;我出于其他一些原因使用object_mapper

      【讨论】:

      • 如果你只有client,你怎么能从client中提取objectMapper
      • @DerekY 我不知道该怎么做。
      【解决方案3】:

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

      @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);
          }
      }
      

      【讨论】:

      • 谢谢。这与我的 3 行代码相比如何:private static JacksonJsonProvider ...(作为评论不清晰,所以我将其添加为答案)
      • 另外,看看依赖注入我想知道你的方法是否适用于泽西客户端?还是只有球衣服务器?
      • @necromancer Client client = ClientBuilder.newClient(); client.register(ObjectMapperContextResolver.class);
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2017-04-22
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      • 2016-12-06
      相关资源
      最近更新 更多