使用多个配置的ObjectMappers
是否可以使用Jackson设置Jersey进行序列化/反序列化?
我希望能够做的是注册“默认”杰克逊ObjectMapper
然后能够注册另一个功能,该功能提供ObjectMapper
一些特殊配置,在某些情况下会“覆盖”“默认”ObjectMapper
。
例如,此ContextResolver
将用于“默认”映射器:
@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class JacksonMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mObjectMapper;
public JacksonMapperProvider() {
mObjectMapper = createMapper();
}
protected abstract ObjectMapper createMapper() {
ObjectMapper mapper = createMapper();
return mapper
.setSerializationInclusion(Include.ALWAYS)
.configure(JsonParser.Feature.ALLOW_COMMENTS, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mObjectMapper;
}
}
此ContextResolver
将覆盖“默认”映射器:
@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class SpecializedMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mObjectMapper;
public SpecializedMapperProvider() {
mObjectMapper = createMapper();
}
protected abstract ObjectMapper createMapper() {
ObjectMapper mapper = createMapper();
return mapper
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"))
.registerModule(new SpecializedModule1())
.registerModule(new SpecializedModule2());
}
@Override
public ObjectMapper getContext(Class<?> type) {
if(SomeType.isAssignableFrom(type)) {
return mObjectMapper;
}
return null;
}
}
我在JacksonJsonProvider
代码中看到杰克逊支持ObjectMapper
提供商注入/解析。然而,在实践中,我所看到的是提供者的“顺序”似乎是随机的(我猜它不是,但我不能理清如何控制顺序)。有时“覆盖”出现在“默认”之前,一切正常,但在下次服务器启动时,订单会发生变化。
我试图通过多种方式实现这一目标,包括:
ContextResolver<ObjectMapper>
实施(按不同顺序)ContextResolver<ObjectMapper>
注释@Provider
实施
我使用以下内容:
也许我采取了一种完全错误的做法? 有没有更好的方法来实现我想要做的事情? 也许我应该只定义两个独立的JAX-RS应用程序,并为每个应用程序配置一个ObjectMapper配置?
答案 0 :(得分:3)
您可以配置提供商的顺序,但在这种情况下最好使用一个提供商:
@Provider
public class JacksonMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper defaultMapper;
private final ObjectMapper specializedMapper;
public JacksonMapperProvider() {
defaultMapper = createDefaultMapper();
specializedMapper = createSpecializedMapper();
}
private static ObjectMapper createDefaultMapper() {
return new ObjectMapper()
.setSerializationInclusion(Include.ALWAYS)
.configure(JsonParser.Feature.ALLOW_COMMENTS, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
}
private static ObjectMapper createSpecializedMapper() {
return new ObjectMapper()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"))
.registerModule(new SpecializedModule1())
.registerModule(new SpecializedModule2());
}
@Override
public ObjectMapper getContext(Class<?> type) {
if (SomeType.isAssignableFrom(type)) {
return specializedMapper;
}
else {
return defaultMapper;
}
}
}
答案 1 :(得分:0)
最新方法是
new ObjectMapper().configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
在最新版本的杰克逊中获得ALLOW_UNQUOTED_FIELD_NAMES。