我正在使用Jersey JAX-RS客户端(版本2.0)。我知道它使用Jackson ObjectMapper来生成和解析JSON。我想使用同一个对象为某些java类生成JSON,以便我可以将它们写入日志。
我知道我可以创建一个新的ObjectMapper实例,但我更愿意请求Jersey客户端给我一个它正在使用的实例。我怎样才能做到这一点? Jersey 2.0知道Jackson,因为它包含一个JacksonFeature类,用于首先配置Jackson功能。
答案 0 :(得分:19)
我通过添加以下静态成员解决了这个问题:
private static JacksonJsonProvider jackson_json_provider = new JacksonJaxbJsonProvider()
.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
private static ObjectMapper object_mapper = jackson_json_provider.locateMapper(
Object.class, MediaType.APPLICATION_JSON_TYPE);
private static Client client = ClientBuilder.newClient().register(jackson_json_provider);
请注意,仅配置FAIL_ON_UNKNOWN_PROPERTIES
或FAIL_ON_EMPTY_BEANS
不需要第二个声明;我出于其他原因使用object_mapper
。
答案 1 :(得分:17)
Jersey实际上并没有显式配置ObjectMapper实例,而是委托给JacksonJsonProvider
,后者又使用默认的映射器实例。您可以追踪the JacksonProviderProxy code以查看其工作原理。您可以通过定义context resolver:
@Provider
public class ObjectMapperContextResolver implements
ContextResolver<ObjectMapper> {
private ObjectMapper mapper = null;
public ObjectMapperContextResolver() {
super();
// Illustrate configuration of the mapper instance
mapper = new ObjectMapper().configure(
SerializationConfig.Feature.WRAP_ROOT_VALUE, true).configure(
DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
Jackson提供程序将从此解析程序中检索其映射器实例,您可以在代码中执行相同操作,如下所示:
public class MyResource {
@Context
private ContextResolver<ObjectMapper> mapperResolver;
public void someResourceMethod() {
final ObjectMapper mapper = mapperResolver.getContext(Object.class);
}
}
答案 2 :(得分:0)
根据此处的其他解决方案(使用jackson 2.8.3)无法到达球衣对象映射器进行配置。 (我怀疑它可能与osgi容器有关,但仍然......)围绕它的一种强力方法是从客户端获取Response对象并在其上调用自己的ObjectMapper实例。然后,同样的实例也可以在其他地方使用显式配置重复使用。
Client client = ClientBuilder.newClient();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
...
Response r = client.target(URL).request().get();
MyDtoClass dto = mapper.readValue((InputStream)(r.getEntity()), MyDtoClass.class);