Настройка JSON маршаллинга с помощью GlassFish v4

У нас есть приложение JAX-RS, которое работает на Apache TomEE. Мы слегка настраиваем поставщика Jettison по умолчанию, чтобы лучше соответствовать соглашениям JSON, используемым в веб-интерфейсе JavaScript. TomEE позволяет сделать это через файл resources.xml:

<resources>
    <Service id="jettison" class-name="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        serializeAsArray = true
        dropRootElement = false
        arrayKeys = members,roles
        supportUnwrapped = true
        writeXsiType = false
    </Service>
</resources>

Сейчас мы переходим на GlassFish v4.1, и мы замечаем, что вывод JSON отличается от того, что мы имели в TomEE, - таким образом, полностью нарушая внешний интерфейс. Я ищу аналогичный механизм для настройки маршаллера JSON в GlassFish. На самом деле, я уже немного застрял с Джерси, МОКСИ, Джексоном, Джеттисоном. Как мы узнаем, какой JSON-провайдер на самом деле используется? Как мы выбираем один? Как мы можем настроить поведение?

Приложение является чистым JAX-RS и не использует напрямую какой-либо процессор JSON, вместо этого полагаясь на маршалинг JAXB-аннотированных классов. Введение любых не-JavaEE-зависимостей крайне нежелательно, так как приложение предназначено для переноса между контейнерами (TomEE, GlassFish, однажды WildFly). Метод файла конфигурации, подобный TomEE, предпочтительнее; Программный способ также приемлем, но только если поддерживается переносимость.

1 ответ

Glassfish использует MOXy в качестве поставщика по умолчанию. Внутренне он имеет библиотеки для обработки Джексона, Джеттисона и MOXy, но по умолчанию используется MOXy. Есть два способа отключить MOXy

  1. Установите свойство Джерси jersey.config.server.disableMoxyJson в true,
  2. Зарегистрировать другой XxxJsonFeature это отключает МОКСИ. Например, JacksonFeature что идет с jersey-media-json-jackson

Обратите внимание, что Glassfish поставляется с поставщиком Jackson, но это Jackson 1.x. Если вы хотите использовать 2.x вместо использования jersey-media-json-jackson зависимость, перечисленная выше, было бы лучше использовать базовую зависимость поставщика Джексона, которая

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.6.0</version>
</dependency>

Вы можете зарегистрировать JacksonJsonProvider или JacksonJaxbJsonProvider для поддержки аннотаций JAXB.

Чтобы настроить Джексона, самый простой способ реализовать ContextResolver, как видно из этого ответа. JacksonJsonProvider будет искать это ContextResolver чтобы получить ObjectMapper используется для (де) сериализации.

Вы также должны помнить, чтобы отключить MOXy, как упоминалось выше.

Также следует отметить, что это решение является портативным. С JAX-RS единственная конфигурация переносимого приложения - через Application подкласс

@ApplicationPath("/api")
public class MyApplication extends Application {}

При этом отключение MOXy в случае Glassfish - это не что иное, как установка свойства. в Application класс, вы можете переопределить getProperties() который возвращает Map<String, Object>, Здесь вы можете установить свойство. И поскольку он не более чем строка (без внешних зависимостей), он остается переносимым

@ApplicationPath("/api")
public class MyApplication extends Application {
    @Override
    public Map<String, Object> getProperties() {
        Map<String, Object> props = new HashMap<>();
        props.put("jersey.config.server.disableMoxyJson", true);
        return props;
    }
}

Что касается вышеуказанной зависимости Джексона, это также портативное решение. Это ничего особенного (JAX-RS) реализации. Он реализует и использует стандартные API JAX-RS

Другие вопросы по тегам