【问题标题】:What is a ContextResolver and Provider in Jersey?Jersey 中的 ContextResolver 和 Provider 是什么?
【发布时间】:2016-06-29 18:26:10
【问题描述】:

什么是泽西岛的ContextResolver,什么是Provider?两者有什么区别?我在泽西岛使用 Genson。当 Jersey 在类路径中找到 Genson JAR 时,Genson 会自动注册。 Genson JAR 的 WEB-INF/services 目录包含一个名为“org.glassfish.jersey.internal.spi.AutoDiscoverable”的文件。

遵循 AutoDiscoverable 路径,默认情况下 Genson/Jersey 会自动注册以下类:

@Provider
@Consumes({MediaType.APPLICATION_JSON, "text/json", "application/*+json"})
@Produces({MediaType.APPLICATION_JSON, "text/json", "application/*+json"})
public class GensonJsonConverter implements MessageBodyReader<Object>, MessageBodyWriter<Object> {

     private final ContextResolver<GensonJaxRSFeature> _gensonResolver;

这里是更多混乱的地方:查看 Genson 文档,它建议创建一个自定义提供程序,如下所示:

    @Provider
    public class GensonProvider implements ContextResolver<Genson> {
    private final Genson genson = new GensonBuilder().setSkipNull(true).create();
    }

但是,该提供程序实现了 ContextResolver 而不是 MessageBodyReader/Writer 就像内部 Genson 那样。有什么不同?此外,该提供商不会与默认自动注册的一样的事情!特别是,它忽略 JAXB 标签,如@XmlTransient!深入研究 GensonJaxRSFeature 的 Genson 源代码,我看到 Genson 对象是这样创建的:

private static final Genson _defaultGenson = new GensonBuilder()
      .withBundle(new JAXBBundle())
      .useConstructorWithArguments(true)
      .create();

从中和 Genson 文档中,我可以看到“JAXBBundle”可能是导致 Genson 关注 JAXB 注释的原因。

主要问题:

我想使用自动注册到 Jersey 的默认 Genson JSON 提供程序,但我想在其上设置一些自定义属性。正如我所说,当我注册我的自定义提供程序时,它不使用默认的 Genson !


更新:

这就是我现在正在做的事情,并且有效。但是,@eugen 下面的解决方案是 Genson 推荐的解决方案。

@Provider
public class GensonProvider implements ContextResolver<GensonJaxRSFeature> {
    private final GensonJaxRSFeature _gensonResolver = new GensonJaxRSFeature();

    private static final Genson _defaultGenson = new GensonBuilder()
              .withBundle(new JAXBBundle())
              .useConstructorWithArguments(true)
              .setSkipNull(true)
              .create();

   @Override
   public GensonJaxRSFeature getContext(Class<?> type) {
        return _gensonResolver.use(_defaultGenson);
   }
}

【问题讨论】:

  • 是什么让您说 Genson 建议定义自定义提供程序?至少当前文档建议使用配置了 GensonJaxRSFeature 的 ResourceConfig,该 GensonJaxRSFeature 使用您的自定义 Genson 实例。您不应该更改默认的 genson 实例。如果您想要另一个配置,只需使用您想要的配置创建另一个实例。
  • @eugen 查看我的编辑,看看我做了什么。 Genson 文档中推荐的代码是“new ResourceConfig().register(new GensonJaxRSFeature().use(myCustomGenson).disableSerializationFor(String.class));”。它的作用与我现在所做的相同,只是我使用的是 Provider 而不是您通常放置“新 ResourceConfig”代码的任何位置。那个“新的 ResourceConfig”通常去哪里?你能发布一个例子或链接吗?
  • 检查 the official docs 以了解如何使用 ResourceConfig。没有办法获取默认的 genson 实例并对其进行修改。只需提供您自己想要的任何配置。是的,如果您希望 Genson 使用 JAXB 注释,您需要将其配置为使用此捆绑包。
  • @eugen 这对我来说没有意义,我已经读了 3 遍了。我已经看到其他示例说将 与您的 package.ClassName 放在 web xml 中并使您的类扩展 Application。如果这就是您所提倡的,我仍然看不到您将代码“new ResourceConfig().register(new GensonJaxRSFeature().use(myCustomGenson).disableSerializationFor(String.class))”放在哪里,因为这些示例通常只需调用寄存器(...)。如果您不想给我举个例子,那么无论如何,但是解释没有通过。
  • @eugen 还有一个问题。你一直暗示我这样做的方式是错误的,但是,我测试了它并且它有效。为什么你认为像我上面提到的带有 ContextResolver 的 Provider 不应该工作?无论如何,感谢您迄今为止的帮助。

标签: java jersey jax-rs genson


【解决方案1】:

就像我们的世界一样,对于同一个问题,有多种解决方案。 Jersey 似乎鼓励使用 ResourceConfig 而不是定义自定义提供程序。所以这就是你如何使用资源配置来实现它(来自 jersey docs here 和 Genson 文档 here)。

public class MyApplication extends ResourceConfig {
    public MyApplication() {
      Genson genson = new GensonBuilder()
              .withBundle(new JAXBBundle())
              .useConstructorWithArguments(true)
              .setSkipNull(true)
              .create();

      register(new GensonJaxRSFeature().use(genson));
    }
}

当然,您使用提供商的方式也可以。

【讨论】:

  • 谢谢,我想我只是在 Genson 文档中对 b/c 感到困惑,它说要创建一个“新的 ResourceConfig()”,但在此解决方案中并非如此。您正在创建一个新的 GensonBuilder,但从未创建一个新的 ResourceConfig()。无论如何,我现在明白了。我主要是确保我没有错过“新资源配置”部分的重要内容...
  • 不,你不会错过任何东西。资源配置似乎是球衣希望我们放置配置部分的地方 - 但您当前的解决方案也很好。是的,这里我们不创建资源配置,而是扩展它。在 Jersey 的其他一些用法中,人们会实例化它(我认为 jetty + jersey 就是这种情况)。
猜你喜欢
  • 2011-03-04
  • 2016-04-22
  • 1970-01-01
  • 2021-06-12
  • 2021-12-25
  • 2023-03-12
  • 2014-08-12
  • 2021-03-06
  • 1970-01-01
相关资源
最近更新 更多