Как извлечь ObjectMapper из JAX-RS Client?
Я использую клиент Джерси JAX-RS (версия 2.0). Я знаю, что использует Jackson ObjectMapper для генерации и анализа JSON. Я хочу использовать тот же самый объект для создания JSON для некоторых классов Java, чтобы я мог записать их в журнал.
Я знаю, что могу создать новый экземпляр ObjectMapper, но я предпочитаю просить Джерси-Клиента дать мне ссылку на тот, который он использует. Как я могу это сделать? Джерси 2.0 знает Джексона, потому что он включает класс JacksonFeature, который используется для настройки функции Джексона в первую очередь.
Ответы
Ответ 1
Я решил это, добавив следующие статические элементы:
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
по другим причинам.
Ответ 2
На самом деле Джерси не явно настраивает экземпляр ObjectMapper, а делегирует его JacksonJsonProvider
, который, в свою очередь, использует экземпляр сопоставления по умолчанию. Вы можете проследить через код JacksonProviderProxy, чтобы узнать, как это работает. Вы можете создавать и настраивать общий сопоставитель, который будет использоваться в вашем приложении, определяя контекстный преобразователь:
@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);
}
}
Ответ 3
Не удалось добраться до устройства отображения джерси, чтобы настроить его, основываясь на других решениях здесь (используя 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);