Доступ к картографическому объекту Jackson в RestEasy
Меня попросили украсть по умолчанию Jackson JSON, выходящего из конечной точки RestEasy. Я провел некоторое исследование Jackson и написал некоторый автономный код, чтобы иметь возможность подавлять нули, настраивать форматы данных и т.д. Теперь задача заключается в том, чтобы вводить этот код в сериализации RestEasy JSON.
Судя по сообщениям форума, это тривиально в Spring, однако, похоже, это не так в RestEasy. Я написал ContextResolver и настроен как resteasy.provider в контексте params в web.xml(на Tomcat), но это предотвращает загрузку webapp на Tomcat.
Теперь я пытаюсь расширить javax.ws.rs.core.Application и предоставить ContextResolver, но ничего не добился. Это прямо, кто-нибудь это сделал? Любая помощь приветствуется.
Ответы
Ответ 1
Хорошо, я понял это, я смог это сделать, написав пользовательский JacksonJsonProvider на основе Jackson FAQ: JAX-RS. Код выглядит следующим образом
@Provider
public class QBOJacksonJsonProvider extends JacksonJsonProvider {
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
@Override
public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
Log.info(getClass(), "In custom JSON provider");
//get the Object Mapper
ObjectMapper mapper = locateMapper(type, mediaType);
// Suppress null properties in JSON output
mapper.getSerializationConfig().setSerializationInclusion(org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL);
// Set human readable date format
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
mapper.getSerializationConfig().setDateFormat(sdf);
super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream);
}
}
Ответ 2
Я нашел более удобный способ изменения Jackson SerializationConfig - вы можете перехватить создание ObjectMapper с помощью ContextResolver JAX-RS.
@Provider
@Produces(Array(MediaType.APPLICATION_JSON))
class JacksonConfig extends ContextResolver[ObjectMapper] {
val mapper = new ObjectMapper()
mapper.getSerializationConfig.setSerializationInclusion(Inclusion.NON_NULL)
def getContext(objectType: Class[_]) = mapper
}
Вам нужно будет зарегистрироваться в RESTEasy одним из следующих способов:
- Вернуть его как класс или экземпляр из реализации javax.ws.rs.core.Application
- Перечислите его как поставщика с resteasy.providers
- Пусть RESTEasy автоматически сканирует его в вашем файле WAR. См. Руководство по конфигурации.
- Вручную добавьте его через ResteasyProviderFactory.getInstance(). registerProvider (Class) или registerProviderInstance (Object)
Ссылка: Документы RESTEasy
Ссылка: Никлас Карлссон на форумах JBoss
Обратите внимание, что это работает с RESTEasy 2.3.2, который поставляется как модуль в JBoss 7.1.1.Final, но не работает с RESTEasy 3.0-beta5.
Ответ 3
Провайдер для Jackson ObjectMapper
должен быть стандартным способом JAX-RS для этого (работает с Джерси), поэтому кажется, что вы также можете пойти с RESTeasy.
Ответ 4
Если вы используете провайдер Jackson2, вам нужно сделать что-то немного отличное от предыдущего ответа. Этот пример будет довольно печатать выходные данные по умолчанию
@Provider
public class JSONProvider extends ResteasyJackson2Provider {
@Override
public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType json, MultivaluedMap<String, Object> headers, OutputStream body) throws IOException {
ObjectMapper mapper = locateMapper(type, json);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
super.writeTo(value, type, genericType, annotations, json, headers, body);
}
}
и зарегистрировать его в вашем веб-xml, если у вас нет авторегистра, добавьте его в свой resteasy.providers context-param
Ответ 5
Если вы используете поставщик Jackson 2.2.x, Resteasy предоставил симпатичная печать аннотации с той, что у поставщика JAXB:
org.jboss.resteasy.annotations.providers.jackson.Formatted
Вот пример:
@GET
@Produces("application/json")
@Path("/formatted/{id}")
@Formatted
public Product getFormattedProduct()
{
return new Product(333, "robot");
}
В качестве примера, показанного выше, @Formatted аннотация позволит базовый вариант Джексона "SerializationFeature.INDENT_OUTPUT".
© Руководство пользователя RESTEasy.
Это не глобальное решение, но вы также можете поместить аннотацию на классы.