Джерси и Guice и хороший JSON - PullRequest
4 голосов
/ 23 июня 2011

У меня есть проект, который использует Jersey 1.7, Guice 3.0 и содержит несколько аннотированных классов JAXB, которые сериализуются через ресурсы в XML и JSON. Я хотел бы сконфигурировать вывод JSON, используя ContextResolver, как предложено в нескольких вопросах здесь о SO, а также в Руководстве пользователя по Джерси . Это включает в себя создание JSONJAXBContext, например:

public class JaxbResolver implements ContextResolver<JAXBContext> {

    private final JAXBContext context;

    public JaxbResolver() throws Exception {
        this.ctx = new JSONJAXBContext(
            JSONConfiguration.
                natural().
                humanReadableFormatting(true).
                build(),
            Resource1.class, Resource2.class);
    }

    /* ... */
}

Моя проблема в том, что некоторые из моих классов ресурсов имеют зависимости, которые должны вводиться Guice, например:

public class DisplayConfigResource {
    private final ConfigRunner cr;

    @com.google.inject.Inject
    public DisplayConfigResource(ConfigRunner cr) {
        this.cr = cr;
    }

    /* ... */
}

Если я удаляю свой JaxbResolver из игры, все работает нормально, за исключением того, что я не имею никакого контроля над сгенерированным JSON (и по умолчанию это очень странно, например, удаление [] s из одноэлементных коллекций, .. .). Так что, кажется, здравый смысл подключать ContextResolver, как мой, к Джерси, чтобы я мог настроить JSON на что-то, что мне нравится. Но

  • классу JSONJAXBContext действительно нравится иметь конструкторы без аргументов в ресурсах, в то время как
  • моим ресурсам действительно нравится вставлять свои зависимости в свои конструкторы.

Итак, мой вопрос: как разрешить эту ситуацию, и чтобы Джерси, Гис и JSON хорошо играли вместе?

Ответы [ 2 ]

2 голосов
/ 24 июня 2011

Вы также можете использовать Джексона вместо JAXB для JSON-маршала / демаршала. Он использует те же аннотации @XmlRootElement, @XmlType и т. Д. И выдает более стандартный вывод (и не нуждается в этих причудливых ContextResolver элементах естественной конфигурации).

Сначала настройте ваш web.xml:

<servlet>
  <servlet-name>jersey</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
  </init-param>
</servlet>

Затем добавьте зависимость jersey-json в ваш файл pom.xml:

<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-json</artifactId>
  <version>1.7</version>
</dependency>
0 голосов
/ 24 июня 2011

У меня была похожая проблема, и я решил ее, создав собственный JAXBContextResolver и вручную указав, какие классы будут хорошо играть с сериализацией json:

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext context;
    private Class<?>[] types = {DtoIdNazov.class, DtoLokalitaPoloha.class, DtoListRestauracie.class, DtoDetailRestauracia.class};

    public JAXBContextResolver() throws Exception {
        JSONConfiguration jsonConfiguration = JSONConfiguration.natural().build();
        this.context = new JSONJAXBContext(jsonConfiguration, types);
    }

    public JAXBContext getContext(Class<?> objectType) {
        for (Class<?> type : types) {
            if (type == objectType) {
                return context;
            }
        }
        return null;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...