什么是 Jersey 中的 ContextResolver 和 Provider?
What is a ContextResolver and Provider in Jersey?
泽西岛的 ContextResolver
是什么,Provider
是什么?两者有什么区别?我正在将 Genson 与 Jersey 一起使用。当 Jersey 在 class 路径上找到 Genson JAR 时,Genson 会自动注册。 Genson JAR 的 WEB-INF/services 目录包含一个名为 "org.glassfish.jersey.internal.spi.AutoDiscoverable" 的文件。
按照 AutoDiscoverable
路径,默认情况下 Genson/Jersey 自动注册以下 class:
@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
而不是像内部 Genson 那样的 MessageBodyReader
/Writer。有什么不同?此外,该提供商不会 做 与默认自动注册的提供商所做的相同的事情!特别是,它 忽略 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);
}
}
在我们的世界里,同一个问题总是有多种解决方案。
Jersey 似乎鼓励使用 ResourceConfig 而不是定义自定义提供程序。这就是使用资源配置(来自 jersey docs here and Genson documentation 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));
}
}
当然,您与提供者合作的方式也很好。
泽西岛的 ContextResolver
是什么,Provider
是什么?两者有什么区别?我正在将 Genson 与 Jersey 一起使用。当 Jersey 在 class 路径上找到 Genson JAR 时,Genson 会自动注册。 Genson JAR 的 WEB-INF/services 目录包含一个名为 "org.glassfish.jersey.internal.spi.AutoDiscoverable" 的文件。
按照 AutoDiscoverable
路径,默认情况下 Genson/Jersey 自动注册以下 class:
@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
而不是像内部 Genson 那样的 MessageBodyReader
/Writer。有什么不同?此外,该提供商不会 做 与默认自动注册的提供商所做的相同的事情!特别是,它 忽略 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);
}
}
在我们的世界里,同一个问题总是有多种解决方案。 Jersey 似乎鼓励使用 ResourceConfig 而不是定义自定义提供程序。这就是使用资源配置(来自 jersey docs here and Genson documentation 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));
}
}
当然,您与提供者合作的方式也很好。