Подтвердить что ты не робот

Доступ к картографическому объекту 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, но ничего не добился. Это прямо, кто-нибудь это сделал? Любая помощь приветствуется.

4b9b3361

Ответ 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.

Это не глобальное решение, но вы также можете поместить аннотацию на классы.