Настройка 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
- Установите свойство Джерси
jersey.config.server.disableMoxyJson
вtrue
, - Зарегистрировать другой
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