如何在jersey2 / hk2应用程序中获取Jackson Object Mapper的引用 [英] How do I get a reference to the Jackson Object Mapper in a jersey2 / hk2 application

查看:144
本文介绍了如何在jersey2 / hk2应用程序中获取Jackson Object Mapper的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个jersey2应用程序,通过Jackson配置为JSON支持,添加

I have a jersey2 application configured for JSON support via Jackson, adding

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>${jersey.version}</version>
</dependency>

public MyApplication() {
    ...
    register(JacksonFeature.class)
    ...
}

。一切正常,我的资源将反序列化的POJO作为参数

in my application. Everything works, my resources get deserialized POJOs as arguments

@POST @Consumes(MediaType.APPLICATION_JSON)
public void blah(MyPojo p) {
    ...
}

现在其中一个资源需要引用Jackson的 ObjectMapper 来自行进行反序列化。我尝试过这样的事情

Now one of thoese resources needs a reference to Jackson's ObjectMapper to do some deserialization on its own. I've tried doing something like

@Inject
public MyResource(@Context ObjectMapper mapper) {
    ...
}

@GET
public String foo(@Context ObjectMapper mapper) {
    ...
}

但在这两种情况下,对 mapper 的引用都为空。如何在我的资源中注入对 ObjectMapper 的引用?

but in both cases the reference to mapper is null. How can I inject a reference to the ObjectMapper in my resources?

推荐答案

首先,杰克逊提供商没有使用默认的 ObjectMapper 。它实际上根本不使用 ObjectMapper 。它利用其他Jackson API来处理(反)序列化。

First there is no default ObjectMapper used by the Jackson provider. It doesn't use an ObjectMapper at all actually. It makes use of other Jackson APIs to handle the (de)serialization.

如果你想使用/注入一个 ObjectMapper 实例,那么你应该为它创建一个 Factory

If you want to use/inject a single ObjectMapper instance, then you should just create a Factory for it

public class ObjectMapperFactory implements Factory<ObjectMapper> {

    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的任何配置 非线程安全。所以说你试图从你的资源方法配置它,那些操作不是线程安全的。

One thing should be noted is that any configuration of the ObjectMapper is not thread safe. So say you tried to configure it from your resource method, those operations are not thread safe.

杰克逊提供商需要注意的另一件事是,如果我们提供一个 ContextResolver ,如@Laurentiu L 提到的,杰克逊提供商将会切换到使用我们的 ObjectMapper 。在这种情况下,如果你想使用相同的 ObjectMapper ,那么你可以在 Factory 中查找。例如

Another thing to note with the Jackson provider, is that if we provide a ContextResolver, like mentioned by @Laurentiu L, then the Jackson provider will switch to using our ObjectMapper. In which case, if you want to use that same ObjectMapper, then you can look it up in the Factory. For example

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) {}   
}

为了使上述工作(使用单个 ObjectMapper ),您需要确保实现 ContextResolver< ObjectMapper> ,并确保使用相应的 @Produces ContextResolver >和 @Consumes 媒体类型。

For the above to work (use a single ObjectMapper), you need to make sure to implement the ContextResolver<ObjectMapper>, and make sure to annotation the ContextResolver with the corresponding @Produces and @Consumes media types.

这篇关于如何在jersey2 / hk2应用程序中获取Jackson Object Mapper的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆