将Jersey中的Jackson与多个已配置的ObjectMapper一起使用
是否可以使用Jackson设置Jersey,以便使用多个已配置的将Jersey中的Jackson与多个已配置的ObjectMapper一起使用,jersey,jackson,jax-rs,jackson-modules,Jersey,Jackson,Jax Rs,Jackson Modules,是否可以使用Jackson设置Jersey,以便使用多个已配置的对象映射器进行序列化/反序列化 我希望能够注册一个“默认”JacksonObjectMapper,然后能够注册另一个功能,该功能提供了一个带有一些特殊配置的ObjectMapper,在某些情况下将“覆盖”默认的ObjectMapper 例如,此ContextResolver将用于“默认”映射器: 我在JacksonJsonProvider代码中看到了Jackson支持的ObjectMapperprovider注入/解析。然而,在实践
对象映射器进行序列化/反序列化
我希望能够注册一个“默认”JacksonObjectMapper
,然后能够注册另一个功能,该功能提供了一个带有一些特殊配置的ObjectMapper
,在某些情况下将“覆盖”默认的ObjectMapper
例如,此ContextResolver
将用于“默认”映射器:
我在JacksonJsonProvider
代码中看到了Jackson支持的ObjectMapper
provider注入/解析。然而,在实践中,我看到的是提供者的“顺序”似乎是随机的(我猜不是,但我无法确定如何控制顺序)。有时“覆盖”在“默认”之前,一切正常,但在下一次服务器启动时,顺序会发生变化
我已尝试通过多种方式实现这一目标,包括:
- 手动注册
ContextResolver
实现(以不同的顺序)
- 通过
@Provider
注释注册ContextResolver
实现
- 注册时指定优先级
我正在使用以下工具:
- 泽西岛2.8
- 杰克逊2.3.3
也许我采取了完全错误的方法?
有没有更好的方法来实现我的目标?
也许我应该定义两个独立的JAX-RS应用程序,并为每个应用程序配置一个ObjectMapper配置?您可以配置提供程序的顺序,但在这种情况下,最好使用一个提供程序:
@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;
}
}
}
@Provider
公共类JacksonMapperProvider实现ContextResolver{
私有最终对象映射器defaultMapper;
私有最终对象映射器specializedMapper;
公共JacksonMapperProvider(){
defaultMapper=createDefaultMapper();
specializedMapper=createSpecializedMapper();
}
私有静态对象映射器createDefaultMapper(){
返回新的ObjectMapper()
.setSerializationInclusion(包括.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\u UNQUOTED\u CONTROL\u CHARS,true);
}
私有静态对象映射器createSpecializedMapper(){
返回新的ObjectMapper()
.disable(序列化功能。将日期写入时间戳)
.setDateFormat(新的SimpleDateFormat(“yyyy-MM-dd'T'HH:MM:ss.SSS”))
.registerModule(新的SpecializedModule1())
.registerModule(新的SpecializedModule 2());
}
@凌驾
公共对象映射器getContext(类类型){
if(SomeType.isAssignableFrom(type)){
返回专业化apper;
}
否则{
返回默认映射器;
}
}
}
最新的方法是
new ObjectMapper().configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
获取jackson最新版本中的ALLOW_UNQUOTED_FIELD_名称。谢谢。这是我最初为使其工作所做的,然而,我希望保持应用程序的不同模块/区域的独立性和不可知性,并避免由于需要不同的映射程序而导致潜在的“大型提供者”。你能详细解释一下为什么“在这种情况下最好使用一个提供者”吗?我有一个类似的问题变得更糟,因为我们想为Jackson注释使用mixin,而不是将它们放在实际的类上。通过创建自己的@JsonMixin
注释,然后在运行时扫描所有注释对象,我们解决了问题。您可以执行类似的操作,动态配置您的ObjectMapper
,并只维护一个。我发现,一旦您拥有ObjectMapper defaultMapper=return new ObjectMapper()
,它就不同于默认的JacksonJsonProvider
实例。至少不适用于JacksonJaxbJsonProvider
。
@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;
}
}
}
new ObjectMapper().configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);