2015-08-18 2 views
2

HTTP-запрос может включать заголовок Accept, указывающий типы (-ы) сообщений, которые клиент найдет приемлемыми. Сервер должен соблюдать запрос, предоставляя ответ, который имеет Content-Type, который соответствует (одному из) запрашиваемых типов (-ов) носителей. Тип носителя может включать в себя параметры . Требует ли HTTP, чтобы этот процесс согласования содержания соответствовал параметрам ?Согласовано ли содержание HTTP-содержимого с параметрами типа носителя

То есть, если клиент запрашивает

Accept: application/vnd.example; version=2 

(здесь параметр version имеет значение 2), и сервер может служить тип носителя application/vnd.example; version=1, но не application/vnd.example; version=2, это нормально для сервера дать ответ с

Content-Type: application/vnd.example; version=1 

это нормально для сервера, чтобы дать ответ меченого

Content-Type: application/vnd.example; version=2 

, но для тела ответа фактически закодирован как медиа-тип application/vnd.example; version=1? То есть, для параметров медиа-типа ответа должно быть неточное описание тела ответа?

Похоже, что Spring MVC 4.1.0 не учитывает параметры медиа-типа при согласовании содержимого и дает ответы, для которых параметры медиа-типа ответа являются неточным описанием тела ответа. Это связано с тем, что метод org.springframework.util.MimeType.isCompatibleWith(MimeType) не проверяет параметры объектов MimeType.

ответ

3

Соответствующий стандарт, RFC 7231 section 3.1.1.1, говорит следующее о медиа-типов:

Тип/подтип может сопровождаться параметрами в виде пар имя = значение.

Так, Accept и Content-Type заголовки могут содержать параметры типа носителя.Он добавляет:

Наличие или отсутствие параметра может быть существенным для обработки медиа-типа, в зависимости от его определения в реестре типа носителя.

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

Spring MVC 4.1.0, кажется, неправильно полностью игнорировать параметры при выполнении согласования контента: класс org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor некорректно использовать org.springframework.util.MimeType.isCompatibleWith(MimeType), или что MimeType.isCompatibleWith(MimeType) метод неверен. Если вы предоставляете Spring несколько HTTP-конвертеров сообщений, которые отличаются только параметрами поддерживаемого типа носителя, Spring не будет надежно выбирать конвертер сообщений HTTP, который имеет тип носителя, который точно соответствует запрошенному типу носителя.


В section 3.1.1.5, где он описывает заголовок Content-Type, он говорит:

Указанный тип носителя определяет как данные формата и как это данные, предназначенные для обработки получателя

Поскольку параметры типа мультимедиа в целом могут отличаться от формата данных, поведение Spring MVC 4.1.0 неверно, предоставляя параметры, которые являются неточными descri ption тела ответа: метод AbstractMessageConverterMethodProcessor.getMostSpecificMediaType(MediaType, MediaType) ошибочен, чтобы вернуть acceptType, а не produceTypeToUse, когда два типа одинаково специфичны.


Однако section 3.4.1, в котором обсуждается согласование содержания (Проактивная Negotiation), отмечает:

Агент пользователя не может полагаться на упреждающие предпочтения переговоров быть последовательно выполнены, так как исходный сервер не может выполните проактивное согласование для запрашиваемого ресурса или можете решить, что отправка ответа, который не соответствует предпочтениям пользователя , лучше, чем отправка 406 (Неприемлемый) ответ.

Так сервер является разрешено дать ответ, не точно соответствуют параметрам медиа-типа запрашиваемых, как откат, когда он не может обеспечить точное соответствие. То есть, он может выбрать ответ с помощью тела ответа application/vnd.example; version=1 с заголовком Content-Type: application/vnd.example; version=1, несмотря на запрос, указывающий Accept: application/vnd.example; version=2, , если и только если, генерирующий действительный ответ application/vnd.example; version=2, будет невозможно.


Это, видимо, неправильное поведение Spring уже есть отчет об ошибке Spring, SPR-10903.Разработчики Spring закрыли его как «Works as Designed», отметив

Я не знаю никакого правила для эффективного сравнения типов носителей с их параметрами. Это действительно зависит от типа мультимедиа ... Если вы на самом деле пытаетесь добиться управления версиями REST через типы носителей, кажется, что наиболее распространенным решением является использование разных типов носителей, поскольку их формат, очевидно, изменился между версиями:

  • "application/vnd.spring.foo.v1+json"
  • "application/vnd.spring.foo.v2+json"
0

Соответствующая спецификация для согласования содержания в HTTP/1.1 - RFC2616, Section 14.1.

Он содержит следующий пример, соответствующий вашему вопросу:

Accept: text/*, text/html, text/html;level=1, */* 

и дает преимущество как

1) text/html;level=1 
2) text/html 
3) text/* 
4) */* 

Так что я думаю, что с уверенностью можно сказать, что text/html;level=1 и text/html различные типы носителей , Я также рассмотрел бы text/html;level=1 и text/html;level=2 как разные.

Так что в вашем примере я думаю, что было бы правильно ответить с ошибкой 406 и не отвечать другим типом носителя.

 Смежные вопросы

  • Нет связанных вопросов^_^