agn*_*nul 9 java json dependency-injection jersey-2.0 hk2
我有一个jersey2应用程序配置为通过杰克逊支持JSON,添加
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
在POM文件中
public MyApplication() {
...
register(JacksonFeature.class)
...
}
Run Code Online (Sandbox Code Playgroud)
在我的申请中.一切正常,我的资源将反序列化的POJO作为参数
@POST @Consumes(MediaType.APPLICATION_JSON)
public void blah(MyPojo p) {
...
}
Run Code Online (Sandbox Code Playgroud)
现在,其中一个资源需要提及杰克逊ObjectMapper自己做一些反序列化.我试过做类似的事情
@Inject
public MyResource(@Context ObjectMapper mapper) {
...
}
Run Code Online (Sandbox Code Playgroud)
要么
@GET
public String foo(@Context ObjectMapper mapper) {
...
}
Run Code Online (Sandbox Code Playgroud)
但在这两种情况下,引用都mapper为null.如何ObjectMapper在我的资源中注入引用?
首先ObjectMapper,Jackson提供商没有使用默认值.它实际上根本不使用ObjectMapper.它利用其他Jackson API来处理(反)序列化.
如果你想使用/注入一个ObjectMapper实例,那么你应该只Factory为它创建一个
public class ObjectMapperFactory implements Factory<ObjectMapper> {
final ObjectMapper mapper = new ObjectMapper();
@Override
public ObjectMapper provide() {
return mapper;
}
@Override
public void dispose(ObjectMapper t) {}
}
Run Code Online (Sandbox Code Playgroud)
然后绑定它
register(new AbstractBinder(){
@Override
public void configure() {
bindFactory(ObjectMapperFactory.class)
.to(ObjectMapper.class).in(Singleton.class);
}
});
Run Code Online (Sandbox Code Playgroud)
应该注意的一点是,任何配置都不ObjectMapper是线程安全的.所以说你试图从资源方法配置它,这些操作不是线程安全的.
与杰克逊提供商另外要注意的是,如果我们提供了ContextResolver,像被@Laurentiu大号提到,那么杰克逊提供商将切换为使用我们的ObjectMapper.在这种情况下,如果你想使用相同的ObjectMapper,那么你可以在中查找Factory.例如
public class ObjectMapperFactory implements Factory<ObjectMapper> {
private final Providers providers;
final ObjectMapper mapper = new ObjectMapper();
public ObjectMapperFactory(@Context Providers providers) {
this.providers = providers;
}
@Override
public ObjectMapper provide() {
ContextResolver<ObjectMapper> resolver = providers.getContextResolver(
ObjectMapper.class, MediaType.APPLICATION_JSON);
if (resolver == null) { return mapper; }
return resolver.getContext(null);
}
@Override
public void dispose(ObjectMapper t) {}
}
Run Code Online (Sandbox Code Playgroud)
要使上述工作(使用单个ObjectMapper),您需要确保实现ContextResolver<ObjectMapper>,并确保ContextResolver使用相应的@Produces和@Consumes媒体类型注释.
| 归档时间: |
|
| 查看次数: |
8999 次 |
| 最近记录: |