Первоначально написано
Себастьеном Делузом в блоге SpringSource
Поддержка Spring Jackson была улучшена в последнее время, чтобы стать более гибкой и мощной. В этой записи блога содержится обновленная информация о наиболее полезных функциях, связанных с Jackson, доступных в Spring Framework 4.x и Spring Boot. Все примеры кода взяты из этого демонстрационного приложения Spring-Jackson-Demo , не стесняйтесь взглянуть на код.
JSON Views
Иногда бывает полезно отфильтровать контекстуальные объекты, сериализованные в тело ответа HTTP. Чтобы обеспечить такие возможности, Spring MVC теперь имеет встроенную поддержку последовательных представлений Джексона .
В следующем примере показано, как использовать @JsonView
для фильтрации полей в зависимости от контекста сериализации — например, получить представление «сводки» при работе с коллекциями и получить полное представление при работе с одним ресурсом:
public class View { interface Summary {} } public class User { @JsonView(View.Summary.class) private Long id; @JsonView(View.Summary.class) private String firstname; @JsonView(View.Summary.class) private String lastname; private String email; private String address; private String postalCode; private String city; private String country; } public class Message { @JsonView(View.Summary.class) private Long id; @JsonView(View.Summary.class) private LocalDate created; @JsonView(View.Summary.class) private String title; @JsonView(View.Summary.class) private User author; private List<User> recipients; private String body; }
Благодаря @JsonView
поддержке Spring MVC можно выбрать для каждого метода обработчика, какое поле должно быть сериализовано:
@RestController public class MessageController { @Autowired private MessageService messageService; @JsonView(View.Summary.class) @RequestMapping("/") public List<Message> getAllMessages() { return messageService.getAll(); } @RequestMapping("/{id}") public Message getMessage(@PathVariable Long id) { return messageService.get(id); } }
В этом примере, если все сообщения получены, сериализуются только самые важные поля благодаря getAllMessages()
методу, помеченному как @JsonView(View.Summary.class)
:
[ { "id" : 1, "created" : "2014-11-14", "title" : "Info", "author" : { "id" : 1, "firstname" : "Brian", "lastname" : "Clozel" } }, { "id" : 2, "created" : "2014-11-14", "title" : "Warning", "author" : { "id" : 2, "firstname" : "Stéphane", "lastname" : "Nicoll" } }, { "id" : 3, "created" : "2014-11-14", "title" : "Alert", "author" : { "id" : 3, "firstname" : "Rossen", "lastname" : "Stoyanchev" } } ]
В Spring MVC для конфигурации по умолчанию MapperFeature.DEFAULT_VIEW_INCLUSION
установлено значение false
. Это означает, что при включении JSON View неаннотированные поля или свойства, такие как body
или recipients
не сериализуемые.
Когда конкретный объект Message
извлекается с использованием getMessage()
метода-обработчика (не указан JSON View), все поля сериализуются, как и ожидалось:
{ "id" : 1, "created" : "2014-11-14", "title" : "Info", "body" : "This is an information message", "author" : { "id" : 1, "firstname" : "Brian", "lastname" : "Clozel", "email" : "[email protected]", "address" : "1 Jaures street", "postalCode" : "69003", "city" : "Lyon", "country" : "France" }, "recipients" : [ { "id" : 2, "firstname" : "Stéphane", "lastname" : "Nicoll", "email" : "[email protected]", "address" : "42 Obama street", "postalCode" : "1000", "city" : "Brussel", "country" : "Belgium" }, { "id" : 3, "firstname" : "Rossen", "lastname" : "Stoyanchev", "email" : "[email protected]", "address" : "3 Warren street", "postalCode" : "10011", "city" : "New York", "country" : "USA" } ] }
В @JsonView
аннотации можно указать только один класс или интерфейс , но вы можете использовать наследование для представления иерархий JSON View (если поле является частью JSON View, оно также будет частью родительского представления). Например, этот метод-обработчик будет сериализовать поля, отмеченные @JsonView(View.Summary.class)
и @JsonView(View.SummaryWithRecipients.class)
:
public class View { interface Summary {} interface SummaryWithRecipients extends Summary {} } public class Message { @JsonView(View.Summary.class) private Long id; @JsonView(View.Summary.class) private LocalDate created; @JsonView(View.Summary.class) private String title; @JsonView(View.Summary.class) private User author; @JsonView(View.SummaryWithRecipients.class) private List<User> recipients; private String body; } @RestController public class MessageController { @Autowired private MessageService messageService; @JsonView(View.SummaryWithRecipients.class) @RequestMapping("/with-recipients") public List<Message> getAllMessagesWithRecipients() { return messageService.getAll(); } }
Представления JSON также могут быть указаны при использовании RestTemplate
HTTP-клиента или MappingJackson2JsonView
путем помещения значения для сериализации в, MappingJacksonValue
как показано в этом примере кода .
JSONP
Как описано в справочной документации , вы можете включить JSONP для @ResponseBody
и ResponseEntity
методы, объявив @ControllerAdvice
компонент, который расширяется, AbstractJsonpResponseBodyAdvice
как показано ниже:
@ControllerAdvice public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice { public JsonpAdvice() { super("callback"); } }
После регистрации такого @ControllerAdvice
компонента будет возможно запросить веб-службу JSON из другого домена с помощью <script />
тега:
<script type="application/javascript" src="http://mydomain.com/1.json?jsonp=parseResponse"> </script>
В этом примере полученная полезная нагрузка будет:
parseResponse({ "id" : 1, "created" : "2014-11-14", ... });
JSONP также поддерживается и автоматически включается при использовании MappingJackson2JsonView
с запросом, у которого есть параметр запроса с именем jsonp или callback. Имена параметров запроса JSONP можно настроить с помощью jsonpParameterNames
свойства.
Поддержка XML
Начиная с версии 2.0, Джексон обеспечивает первоклассную поддержку для некоторых других форматов данных, чем JSON. Spring Framework и Spring Boot предоставляют встроенную поддержку сериализации / десериализации XML на основе Jackson.
Как только вы включаете jackson-dataformat-xml
зависимость в ваш проект, она автоматически используется вместо JAXB2.
Использование расширения Jackson XML имеет несколько преимуществ перед JAXB2:
- Аннотации Джексона и JAXB признаны
- Поддерживаются JSON View, что позволяет легко создавать веб-сервисы REST с одинаковым фильтрованным выводом для форматов данных XML и JSON.
- Нет необходимости аннотировать ваш класс
@XmlRootElement
, каждый класс, сериализуемый в JSON, будет сериализуем в XML
Обычно вы также хотите убедиться, что используемой библиотекой XML является Woodstox, поскольку:
- Это быстрее, чем реализация Stax, предоставляемая JDK
- Это позволяет избежать некоторых известных проблем, таких как добавление ненужных префиксов пространства имен
- Некоторые функции, такие как красивая печать, не работают без нее
Чтобы использовать его, просто добавьте последнюю woodstox-core-asl
доступную зависимость для вашего проекта.
Настройка Джексона ObjectMapper
До Spring Framework 4.1.1 Джексон HttpMessageConverter
использовал ObjectMapper
конфигурацию по умолчанию. Чтобы обеспечить лучшую и легко настраиваемую конфигурацию по умолчанию, Jackson2ObjectMapperBuilder
была введена новая . Это эквивалент JavaConfig хорошо известного, Jackson2ObjectMapperFactoryBean
используемого в конфигурации XML.
Jackson2ObjectMapperBuilder
предоставляет приятный API для настройки различных параметров Jackson, сохраняя Spring Framework по умолчанию. Это также позволяет создавать ObjectMapper
и XmlMapper
экземпляры, основанные на той же конфигурации.
И то, Jackson2ObjectMapperBuilder
и другое Jackson2ObjectMapperFactoryBean
определяет лучшую конфигурацию Джексона по умолчанию. Например, для DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
свойства установлено значение false, чтобы разрешить десериализацию объектов JSON с несопоставленными свойствами.
Поддержка Джексоном типов данных API даты и времени Java 8 автоматически регистрируется при использовании Java 8 и jackson-datatype-jsr310
находится на пути к классам. Поддержка Joda-Time также регистрируется, когда она jackson-datatype-joda
является частью вашего проекта.
Эти классы также позволяют легко регистрировать миксины Джексона , модули , сериализаторы или даже стратегии именования свойств, например, PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
если вы хотите userName
преобразовать свое свойство java user_name
в JSON.
С весенней загрузкой
Как описано в справочной документации Spring Boot, существуют различные способы настройки Jackson ObjectMapper
.
Например , вы можете включить / выключить Джексон особенности легко добавляя свойства , как spring.jackson.serialization.indent_output=true
в application.properties
.
В качестве альтернативы, в следующей версии 1.2 Spring Boot также позволяет настроить конфигурацию Джексона (JSON и XML), используемую Spring MVC HttpMessageConverter
, объявив Jackson2ObjectMapperBuilder
@Bean
:
@Bean public Jackson2ObjectMapperBuilder jacksonBuilder() { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd")); return builder; }
Это полезно, если вы хотите использовать расширенную конфигурацию Джексона, не доступную через обычные ключи конфигурации.
Без весенней загрузки
В простом приложении Spring Framework вы также можете использовать Jackson2ObjectMapperBuilder
для настройки XML и JSON, HttpMessageConverter
как показано ниже:
@Configuration @EnableWebMvc public class WebConfiguration extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd")); converters.add(new MappingJackson2HttpMessageConverter(builder.build())); converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); } }
Еще не все
В следующем выпуске Spring Framework 4.1.3 благодаря добавлению контекста Spring HandlerInstantiator
(см. SPR-10768 для более подробной информации) вы сможете автоматически связывать обработчики Jackson (сериализаторы, десериализаторы, преобразователи идентификаторов типов и типов).
Это позволит вам создать, например, пользовательский десериализатор, который заменит поле, содержащее только ссылку в полезной нагрузке JSON, на полное, Entity
извлеченное из базы данных.