在 Jackson 中对单个实体使用两个 JsonSerializer

Using two JsonSerializers for single entity in Jackson

我找到了一种方法来实现我自己的序列化方法,扩展 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 的简明形式和冗长的形式。

您可以实现一个特殊的 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;
    }

}

在您的资源中 class:

@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 并仅为这种类型注册你的序列化程序。