如何在jersey2 / hk2应用程序中获取Jackson Object Mapper的引用
我有一个jersey2应用程序配置为通过jackson支持JSON,添加
org.glassfish.jersey.media jersey-media-json-jackson ${jersey.version}
在POM文件中
public MyApplication() { ... register(JacksonFeature.class) ... }
在我的申请中。 一切正常,我的资源将反序列化的POJO作为参数
@POST @Consumes(MediaType.APPLICATION_JSON) public void blah(MyPojo p) { ... }
现在,其中一个资源需要引用Jackson的ObjectMapper
来自行进行反序列化。 我尝试过这样的事情
@Inject public MyResource(@Context ObjectMapper mapper) { ... }
要么
@GET public String foo(@Context ObjectMapper mapper) { ... }
但在这两种情况下,对mapper
的引用都为null。 如何在我的资源中注入对ObjectMapper
的引用?
首先,Jackson提供商没有使用默认的ObjectMapper
。 它实际上根本不使用ObjectMapper
。 它利用其他Jackson API来处理(反)序列化。
如果你想使用/注入一个ObjectMapper
实例,那么你应该为它创建一个Factory
public class ObjectMapperFactory implements Factory { final ObjectMapper mapper = new ObjectMapper(); @Override public ObjectMapper provide() { return mapper; } @Override public void dispose(ObjectMapper t) {} }
然后绑定它
register(new AbstractBinder(){ @Override public void configure() { bindFactory(ObjectMapperFactory.class) .to(ObjectMapper.class).in(Singleton.class); } });
需要注意的一点是, ObjectMapper
任何配置都不是线程安全的 。 所以说你试图从资源方法配置它,这些操作不是线程安全的。
jackson提供者需要注意的另一件事是,如果我们提供一个ContextResolver ,就像@Laurentiu L所提到的那样 ,那么Jackson提供者将转而使用我们的ObjectMapper
。 在这种情况下,如果您想使用相同的ObjectMapper
,那么您可以在Factory
查找它。 例如
public class ObjectMapperFactory implements Factory { private final Providers providers; final ObjectMapper mapper = new ObjectMapper(); public ObjectMapperFactory(@Context Providers providers) { this.providers = providers; } @Override public ObjectMapper provide() { ContextResolver resolver = providers.getContextResolver( ObjectMapper.class, MediaType.APPLICATION_JSON); if (resolver == null) { return mapper; } return resolver.getContext(null); } @Override public void dispose(ObjectMapper t) {} }
为了使上述工作(使用单个ObjectMapper
),您需要确保实现ContextResolver
,并确保使用相应的@Produces
和@Consumes
媒体类型注释@Consumes
。
除了JacksonFeature之外,您还需要为ObjectMapper注册ContextResolver。
9.1.4.2中的文档中的简单示例。 配置并注册
@Provider public class MyObjectMapperProvider implements ContextResolver
{ final ObjectMapper defaultObjectMapper; public MyObjectMapperProvider() { defaultObjectMapper = createDefaultMapper(); } @Override public ObjectMapper getContext(Class> type) { return defaultObjectMapper; } private static ObjectMapper createDefaultMapper() { final ObjectMapper result = new ObjectMapper(); result.configure(Feature.INDENT_OUTPUT, true); return result; } // ... }
Github上提供了完整的代码示例
您还需要注册它
.register(MyObjectMapperProvider.class)
- 注入私人,包装或公共领域或提供制定者?
- 注释驱动的dependency injection,处理不同的环境
- Java Guice – 如何将整数值绑定到我的类/对象?
- 如何使用Guice @Inject到现有的对象层次结构?
- ClassCastException:org.springframework.orm.jpa.EntityManagerHolder无法强制转换为org.springframework.orm.hibernate5.SessionHolder
- 在JSF 2.0中注入Bean
- 配置Guice模块提供的对象
- Java EE 6 @Inject懒惰?
- Android TestCase中的Dagger 2dependency injection