我使用Jersey 2.9和Jackson 2.5.1在RESTful API上生成JSON响应。
为了提供自定义ObjectMapper
,我实现了ContextResolver
,如下所示:
@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
@Context UriInfo uriInfo;
private final ObjectMapper objectMapper;
public ObjectMapperProvider() {
objectMapper = new ObjectMapper();
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
objectMapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
}
@Override
public ObjectMapper getContext(Class<?> type) {
// TODO: configure custom object mapper depending on query string params
return objectMapper;
}
}
第一次访问端点时效果很好:调用getContext
方法,并根据用户提供的查询字符串对objectmapper执行自定义配置(可能返回一个新配置)。
但是,一旦端点被访问过一次,Jersey似乎会缓存该对象映射器,并且再也不会要求它再次调用getContext
。我需要禁用或阻止此行为,因为查询字符串可能已更改,我可能需要为该请求返回不同的对象映射器。
这可能吗?
谢谢!
答案 0 :(得分:1)
请注意,对象映射器的创建成本相对较高。它是线程安全的designed to be reused。因此,您可以考虑在不创建新映射器实例的情况下为每个请求自定义the Jackson JAX-RS provider,而不是创建自己的上下文。
有几种方法可以实现这一目标。
您可以使用the Jackson specific annotations注释资源方法。例如:
@JacksonFeatures(serializationEnable
= { SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS })
public void foo() {}
但是,这并不允许将请求参数传递给对象映射器。
另一种选择是创建ObjectWriterModifier/ObjectReaderModifier的实例,并通过ObjectWriterInjector / ObjectReaderInjector通过线程本地注入来注册它。请参阅example。
您还可以尝试组合per-request scope context provider和线程本地修改。