Spring MVC Согласование содержания

Spring MVC Content Congotiation

1. обзор

В этой статье описывается, как реализовать согласование содержимого в проекте Spring MVC.

Как правило, существует три варианта определения типа носителя для запроса:

  • Использование суффиксов (расширений) URL в запросе (например,.xml/.json)

  • Использование параметра URL в запросе (например,?format=json)

  • Использование заголовкаAccept в запросе

По умолчанию это порядок, в котором менеджер согласований содержимого Spring будет пытаться использовать эти три стратегии. И если ни один из них не включен, мы можем указать запасной тип контента по умолчанию.

2. Стратегии согласования контента

Начнем с необходимых зависимостей - мы работаем с представлениями JSON и XML, поэтому в этой статье мы будем использовать Jackson для JSON:


    com.fasterxml.jackson.core
    jackson-core
    2.7.2


    com.fasterxml.jackson.core
    jackson-databind
    2.7.2

Для поддержки XML мы можем использовать либо JAXB, XStream, либо более новую поддержку Jackson-XML.

Поскольку мы объяснили использование заголовкаAccept вan earlier article onHttpMessageConverters,, давайте подробно остановимся на первых двух стратегиях.

3. Стратегия URL-суффикса

По умолчанию эта стратегия отключена, но платформа может проверять расширение пути прямо из URL-адреса, чтобы определить тип выходного содержимого.

Прежде чем переходить к настройкам, давайте кратко рассмотрим пример. У нас есть следующая простая реализация метода API в типичном контроллере Spring:

@RequestMapping(
  value = "/employee/{id}",
  produces = { "application/json", "application/xml" },
  method = RequestMethod.GET)
public @ResponseBody Employee getEmployeeById(@PathVariable long id) {
    return employeeMap.get(id);
}

Давайте вызовем его, используя расширение JSON, чтобы указать тип носителя ресурса:

curl http://localhost:8080/spring-mvc-basics/employee/10.json

Вот что мы можем получить, если будем использовать расширение JSON:

{
    "id": 10,
    "name": "Test Employee",
    "contactNumber": "999-999-9999"
}

А вот как будет выглядеть запрос-ответ с XML:

curl http://localhost:8080/spring-mvc-basics/employee/10.xml

Тело ответа:


    999-999-9999
    10
    Test Employee

Now:

Теперьif we do not use any extension или используйте тот, который не настроен - будет возвращен тип содержимого по умолчанию:

curl http://localhost:8080/spring-mvc-basics/employee/10

Теперь давайте посмотрим, как настроить эту стратегию - как с конфигурациями Java, так и с XML.

3.1. Конфигурация Java

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(true).
    favorParameter(false).
    ignoreAcceptHeader(true).
    useJaf(false).
    defaultContentType(MediaType.APPLICATION_JSON);
}

Поговорим о деталях.

Во-первых, мы включаем стратегию расширения пути.

Затем мы отключаем стратегию параметров URL, а также стратегию заголовкаAccept, потому что мы хотим полагаться только на способ расширения пути при определении типа контента.

Затем мы отключаем Java Activation Framework; JAF можно использовать в качестве резервного механизма для выбора формата вывода, если входящий запрос не соответствует ни одной из настроенных нами стратегий. Мы отключаем его, потому что собираемся настроить JSON в качестве типа содержимого по умолчанию.

И наконец - мы устанавливаем JSON по умолчанию. Это означает, что если ни одна из двух стратегий не совпадает, все входящие запросы будут сопоставлены с методом контроллера, который обслуживает JSON.

3.2. Конфигурация XML

Давайте также быстро рассмотрим ту же самую конфигурацию, только с использованием XML:


    
    
    
    
    

4. Стратегия параметров URL

В предыдущем разделе мы использовали расширения пути - теперь давайте настроим Spring MVC для использования параметра пути.

Мы можем включить эту стратегию, установив для свойстваfavorParameter значение true.

Давайте быстро посмотрим, как это будет работать с нашим предыдущим примером:

curl http://localhost:8080/spring-mvc-basics/employee/10?mediaType=json

А вот что будет в теле ответа JSON:

{
    "id": 10,
    "name": "Test Employee",
    "contactNumber": "999-999-9999"
}

Если мы используем параметр XML, вывод будет в форме XML:

curl http://localhost:8080/spring-mvc-basics/employee/10?mediaType=xml

Тело ответа:


    999-999-9999
    10
    Test Employee

Теперь займемся настройкой - снова сначала с использованием Java, а затем XML.

4.1. Конфигурация Java

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(false).
    favorParameter(true).
    parameterName("mediaType").
    ignoreAcceptHeader(true).
    useJaf(false).
    defaultContentType(MediaType.APPLICATION_JSON).
    mediaType("xml", MediaType.APPLICATION_XML).
    mediaType("json", MediaType.APPLICATION_JSON);
}

Давайте прочитаем эту конфигурацию.

Во-первых, конечно, расширение пути и стратегии заголовкаAccept отключены (как и JAF).

В остальном конфигурация такая же.

4.2. Конфигурация XML


    
    
    
    
    
    

    
        
            
            
        
    

Также мы можем одновременно иметьboth strategies (extension and parameter) enabled:

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(true).
    favorParameter(true).
    parameterName("mediaType").
    ignoreAcceptHeader(true).
    useJaf(false).
    defaultContentType(MediaType.APPLICATION_JSON).
    mediaType("xml", MediaType.APPLICATION_XML).
    mediaType("json", MediaType.APPLICATION_JSON);
}

В этом случае Spring сначала будет искать расширение пути, если его нет, будет искать параметр пути. И если оба из них не доступны во входном запросе, тогда тип контента по умолчанию будет возвращен обратно.

5. Стратегия заголовкаAccept

Если заголовокAccept включен, Spring MVC будет искать его значение во входящем запросе, чтобы определить тип представления.

Мы должны установить дляignoreAcceptHeader значение false, чтобы включить этот подход, и мы отключаем две другие стратегии, чтобы знать, что мы полагаемся только на заголовокAccept.

5.1. Конфигурация Java

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.favorPathExtension(true).
    favorParameter(false).
    parameterName("mediaType").
    ignoreAcceptHeader(false).
    useJaf(false).
    defaultContentType(MediaType.APPLICATION_JSON).
    mediaType("xml", MediaType.APPLICATION_XML).
    mediaType("json", MediaType.APPLICATION_JSON);
}

5.2. Конфигурация XML


    
    
    
    
    
    

    
        
            
            
        
    

Наконец, нам нужно включить диспетчер согласования контента, подключив его к общей конфигурации:

6. Заключение

И мы сделали. Мы посмотрели на то, как согласование контента работает в Spring MVC, и сосредоточились на нескольких примерах его настройки для использования различных стратегий для определения типа контента.

Полную реализацию этой статьи можно найти вthe github project - это проект на основе Eclipse, поэтому его будет легко импортировать и запускать как есть.