【问题标题】:Using two JsonSerializers for single entity in Jackson在杰克逊中为单个实体使用两个 JsonSerializer
【发布时间】:2015-06-15 11:38:42
【问题描述】:

我找到了一种方法来实现我自己的扩展JsonSerializer<Foo> 的序列化方法,覆盖serialize() 方法并将SimpleModule 注册到所有内容。这是我所拥有的:

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonConfig implements ContextResolver<ObjectMapper> {


    @Override
    public ObjectMapper getContext(Class<?> aClass) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        SimpleModule fooModule = new SimpleModule("FooModule",
                                      new Version(0, 1, 0, null, "org.foo.bar", "foo"));
        relationshipModule.addSerializer(Foo.class, new FooJacksonSerializer());
        relationshipModule.addDeserializer(Foo.class, new FooJacksonDeserializer());
        mapper.registerModule(fooModule);
        return mapper;
    }
}

但是,有没有办法使用两种自定义序列化策略并根据 REST 请求(我使用 RestEasy)选择正确的一种? IE。即时以编程方式更改它,而不是在设置上下文时。我想要Foo 的简洁形式和详细的形式。

【问题讨论】:

    标签: java jackson resteasy


    【解决方案1】:

    您可以实现一个特殊的 ObjectMapper 并手动获取您需要的:

    @Provider
    @Produces(MediaType.APPLICATION_JSON)
    public class JacksonConfig implements ContextResolver<ObjectMapper> {
    
        private ObjectMapper objectMapper;
    
        private SpecialObjectMapper specialObjectMapper; // a class extending ObjectMapper
    
        public JacksonConfig() {
            objectMapper = new ObjectMapper();
            // configuration ...
            specialObjectMapper = new SpecialObjectMapper();
            // configuration with module ...
        }
    
        @Override
        public ObjectMapper getContext(Class<?> clazz) {
            return clazz == SpecialObjectMapper.class ? specialObjectMapper : objectMapper;
        }
    
    }
    

    在您的资源类中:

    @Context 
    private Providers providers;
    
    public String get() {
        ContextResolver<ObjectMapper> contextResolver = 
            providers.getContextResolver(ObjectMapper.class, MediaType.APPLICATION_JSON_TYPE);
        ObjectMapper mapper = someCondition 
            ? contextResolver.getContext(SpecialObjectMapper.class) 
            : contextResolver.getContext(ObjectMapper.class);
        return mapper.writeValueAsString(value);
    }
    

    我不知道你的目标是什么,但也许你也可以使用Jackson's JSON Views 来实现它,或者定义一个像application/vnd.com.foo.bar.foo+json 这样的自定义 MediaType 并仅为这种类型注册你的序列化程序。

    【讨论】:

    • 谢谢,这些视图看起来很有希望,因为 JAX-RS 方法可以用它们进行注释。不幸的是,我的用例稍微复杂一点,它不仅涉及隐藏实体中的某些字段,还涉及以不同方式呈现它们。有没有办法为某些视图设置自定义序列化程序?
    • 以不同的方式呈现它们听起来像是不同的表示,所以自定义 MediaType 应该适合这里?
    • 它是 json-ld(en.wikipedia.org/wiki/JSON-LD) mime 类型应该是普通的 application/json 但它很冗长,所以我也想要一些相同数据的简洁方式。我最终得到了您最初的建议,非常感谢!
    • 不确定我是否理解正确:您的特殊序列化程序序列化 json-ld,而普通序列化程序序列化普通 json,但您想对两者使用相同的 MimeType?
    • 是的,两者的 MimeType 应该相同。这是我最终得到的 git.io/vLrIK 。谢谢,再次
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多