use*_*535 11 java jersey guice jackson
我似乎无法正确注册我的Jackson ObjectMapper模块.
我正在使用Guice + Jersey + Jackson(FasterXML)堆栈.
我已经按照如何基于各种问题自定义了ObjectMapper.特别是,我声明了一个ContextResolver,标记为@ javax.ws.rs.ext.Provider和@javax.inject.Singleton.
我有一个GuiceServletContextListener:
@Override
protected Injector getInjector() {
Injector injector = Guice.createInjector(new DBModule(dataSource),
new ServletModule()
{
@Override
protected void configureServlets() {
// Mapper
bind(JacksonOMP.class).asEagerSingleton();
// ...
Map<String, String> initParams = new HashMap<String, String>();
initParams.put("com.sun.jersey.config.feature.Trace",
"true");
initParams.put("com.sun.jersey.api.json.POJOMappingFeature", "true");
serve("/services/*").with(
GuiceContainer.class,
initParams);
}
});
return injector;
}
Run Code Online (Sandbox Code Playgroud)
映射器已定义
import javax.inject.Singleton;
import javax.ws.rs.Produces;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
@Provider
@Singleton
@Produces
public class JacksonOMP implements ContextResolver<ObjectMapper> {
@Override
public ObjectMapper getContext(Class<?> aClass) {
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Hibernate4Module());
return mapper;
}
}
Run Code Online (Sandbox Code Playgroud)
但是 - 仅使用此配置,从不调用getContext(),因此从不注册映射器.我陷入了一种典型的诡计 - 注释 - 神秘,它实际上无法实现我实际应该做的事情.Spring用户只报告注册组件,容器只是选择它.
这个答案谈到覆盖我自己的javax.ws.rs.core.Application实现.然而,这看起来很难在GuiceContainer的jersey-guice强制实现DefaultResourceConfig():
@Override
protected ResourceConfig getDefaultResourceConfig(Map<String, Object> props,
WebConfig webConfig) throws ServletException {
return new DefaultResourceConfig();
}
Run Code Online (Sandbox Code Playgroud)
我是否认为GuiceContainer是子类?还是有一些我遗漏的魔法注释?
这似乎是一件相当普遍的事情 - 我很惊讶这种guice组合有多么难以证明.
Vla*_*eev 24
我陷入了一种典型的诡计 - 注释 - 神秘,它实际上无法实现我实际应该做的事情.Spring用户只报告注册组件,容器只是选择它.
你真的应该阅读优秀的Guice文档.Guice非常易于使用,它具有非常少量的基本概念.你的问题在于你混合了Jersey JAX-RS依赖注入和Guice依赖注入.如果您正在使用,GuiceContainer那么您声明您将使用Guice 来处理所有 DI,因此您必须使用Guice添加绑定而不是使用JAX-RS.
例如,你不需要ContextResolver,你应该使用普通的Guice Provider:
import com.google.inject.Provider;
public class ObjectMapperProvider implements Provider<ObjectMapper> {
@Override
public ObjectMapper get() {
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Hibernate4Module());
return mapper;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你应该为你的模块添加相应的绑定:
bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class).in(Singleton.class);
Run Code Online (Sandbox Code Playgroud)
这将绑定ObjectMapper,但仅使用泽西与杰克逊是不够的.你需要某种MessageBodyReader/ MessageBodyWriter,例如JacksonJsonProvider.您将需要另一个提供商:
public class JacksonJsonProviderProvider implements Provider<JacksonJsonProvider> {
private final ObjectMapper mapper;
@Inject
JacksonJsonProviderProvider(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public JacksonJsonProvider get() {
return new JacksonJsonProvider(mapper);
}
}
Run Code Online (Sandbox Code Playgroud)
然后绑定它:
bind(JacksonJsonProvider.class).toProvider(JacksonJsonProviderProvider.class).in(Singleton.class);
Run Code Online (Sandbox Code Playgroud)
这就是您需要做的 - 不需要子类化.
虽然有一个代码大小优化的空间.如果我是你,我会使用@Provides-methods:
@Provides @Singleton
ObjectMapper objectMapper() {
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Hibernate4Module());
return mapper;
}
@Provides @Singleton
JacksonJsonProvider jacksonJsonProvider(ObjectMapper mapper) {
return new JacksonJsonProvider(mapper);
}
Run Code Online (Sandbox Code Playgroud)
应将这些方法添加到您的某个模块中,例如匿名ServletModule.那么您将不需要单独的提供程序类.
顺便说一下,你应该使用JerseyServletModule而不是普通的ServletModule,它为你提供了很多有用的绑定.
| 归档时间: |
|
| 查看次数: |
10205 次 |
| 最近记录: |