Доступ к Jackson Object Mapper в RestEasy - PullRequest
26 голосов
/ 14 декабря 2011

Меня попросили украсить Jackson JSON по умолчанию, выходящий из конечной точки RestEasy.Я провел некоторое исследование Джексона и написал отдельный код, чтобы иметь возможность подавлять пустые значения, настраивать форматы данных и т. Д. Теперь задача заключается в том, чтобы внедрить этот код в сериализацию JSON RestEasy.

Судя по сообщениям на форуме, весной это тривиально, но в RestEasy этого не происходит.Я написал ContextResolver и настроил его как resteasy.provider в параметрах контекста в web.xml (на Tomcat), но это не позволяет загружать веб-приложение на Tomcat.

Теперь я пытаюсь расширить javax.ws.rs.core.Application и предоставить ContextResolver, но безуспешно.Это прямо вперед, кто-нибудь сделал это?Любая помощь с благодарностью.

Ответы [ 6 ]

15 голосов
/ 17 декабря 2011

Хорошо, я понял это, я смог сделать это, написав собственный 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);
    }
}
14 голосов
/ 13 мая 2013

Я нашел более удобный способ изменения Jackson SerializationConfig - вы можете перехватить создание ObjectMapper с помощью Context-Resolver 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 docs

Ссылка: Никлас Карлссон на форумах JBoss

Обратите внимание, что это работает с RESTEasy 2.3.2, которая поставляется как модуль в JBoss 7.1.1.Final, но не отображаетсяработать с RESTEasy 3.0-beta5.

2 голосов
/ 03 мая 2014

Если вы используете провайдера 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);
  }

}

и для регистрации его в вашем web-xml, если у вас нет автоматической регистрации, добавьте его в ваш контекстный параметр resteasy.providers

2 голосов
/ 15 декабря 2011

Поставщик для Джексона ObjectMapper должен быть стандартным способом JAX-RS для этого (работает с Джерси), так что похоже на то же самое и с RESTeasy.

1 голос
/ 11 июля 2018

У меня было много работы, чтобы зарегистрировать его в моем приложении, даже следуя совету по использованию context-param, когда я использую весеннюю загрузку и у меня нет web.xml, вот что я сделал

Пользовательский провайдер

package com.mageddo;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;

@Provider
@Consumes({"application/json", "application/*+json", "text/json"})
@Produces({"application/json", "application/*+json", "text/json"})
public class CustomJacksonJsonProvider extends ResteasyJackson2Provider {

    private ObjectMapper objectMapper = new ObjectMapper(); // my own object mapper

    @Override
    public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) {
        return objectMapper;
    }
}

Регистрация по заявке

META-INF / services / javax.ws.rs.ext.Providers

com.mageddo.CustomJacksonJsonProvider
org.jboss.resteasy.plugins.providers.jackson.UnrecognizedPropertyExceptionHandler
0 голосов
/ 04 мая 2017

Если вы используете провайдер 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 .

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

...