在 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
并仅为这种类型注册你的序列化程序。
我找到了一种方法来实现我自己的序列化方法,扩展 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
并仅为这种类型注册你的序列化程序。