在Jersey中使用Jackson,配置多个ObjectMappers [英] Using Jackson in Jersey with multiple configured ObjectMappers
问题描述
使用多个已配置的 ObjectMappers
,是否可以使用Jackson设置Jersey进行序列化/反序列化?
Is it possible to setup Jersey using Jackson for serialization/deserialization using multiple configured ObjectMappers
?
我是什么我希望能够做的是注册一个默认Jackson ObjectMapper
,然后能够注册另一个提供 ObjectMapper $的功能c $ c>有一些特殊配置,在某些情况下会覆盖默认
ObjectMapper
。
What I would like to be able to do is register a "default" Jackson ObjectMapper
and then have the ability to register another feature which provides an ObjectMapper
with some specialized configuration which under certain circumstance will "override" the "default" ObjectMapper
.
例如,此 ContextResolver
将用于默认映射器:
For example, this ContextResolver
would be for the "default" mapper:
@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中看到
Jackson支持的代码 ObjectMapper
提供者注入/解析。然而,在实践中,我所看到的是提供者的顺序似乎是随机的(我猜它不是,但我不能理清如何控制顺序)。有时覆盖出现在默认之前,一切正常,但在下一次服务器启动时,订单会发生变化。
I see in the JacksonJsonProvider
code that Jackson supports ObjectMapper
provider injection/resolution. However, in practice, what I am seeing is that the "order" of the providers seems random (I'm guessing it's not, but I can't sort out how to control the order). Sometimes the "override" comes before the "default" and everything works, but on the next server startup the order changes.
我试图通过多种方式实现这一目标,包括:
I have attempted to get this to work in a number of ways including:
- 手动注册
ContextResolver< ObjectMapper>
实现(按不同的顺序) - 注册
ContextResolver< ObjectMapper> ;
实施@Provider
注释 - 注册时指定优先级
- Registering the
ContextResolver<ObjectMapper>
implementations manually (in differing orders) - Registering the
ContextResolver<ObjectMapper>
implementations via@Provider
annotations - Specifying a priority when registering
我使用以下内容:
- Jersey 2.8
- Jackson 2.3.3
也许我采取了一种完全不正确的方法?
Is有更好的方法来实现我想要做的事情吗?
也许我应该只定义两个独立的JAX-RS应用程序并为每个应用程序配置一个ObjectMapper?
Perhaps I am taking a completely incorrect approach?
Is there a better way to achieve what I am trying to do?
Maybe I should just define two separate JAX-RS applications and have a single ObjectMapper configuration for each?
推荐答案
你可以配置提供商的顺序,但实际上最好在这种情况下使用一个提供商:
You can configure the order of providers, but it would actually be best to use one provider in this situation:
@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;
}
}
}
这篇关于在Jersey中使用Jackson,配置多个ObjectMappers的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!