HTTP内容协商是否遵循媒体类型参数 [英] Does HTTP content negotiation respect media type parameters

查看:134
本文介绍了HTTP内容协商是否遵循媒体类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

HTTP请求可以包含 Accept 标头,指示客户端可以接受的响应的媒体类型。服务器应通过提供与所请求的媒体类型(一个)匹配的 Content-Type 的响应来兑现请求。媒体类型可以包括参数。 HTTP是否要求此内容协商过程尊重参数

An HTTP request can include an Accept header, indicating the media type(s) of responses that the client will find acceptable. The server should honour the request by providing a response that has a Content-Type that matches (one of) the requested media type(s). A media type may include parameters. Does HTTP require that this process of content-negotiation respect parameters?

即如果客户请求

 Accept: application/vnd.example; version=2

(此处为版本参数的值为 2 ),服务器可以提供媒体类型 application / vnd.example; version = 1 ,但不是 application / vnd.example; version = 2 ,服务器是否可以提供回复

(here the version parameter has a value of 2), and the server can serve media-type application/vnd.example; version=1, but not application/vnd.example; version=2, is it OK for the server to provide a response with

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

服务器是否可以提供标有

Is it OK for the server to provide a response labelled

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

但是对于实际被编码为媒体类型<$ c的响应的主体$ C>应用/ vnd.example;版本= 1 ?也就是说,对于响应的媒体类型的参数是对响应主体的不准确描述?

but for the body of the response to actually be encoded as media-type application/vnd.example; version=1? That is, for the parameters of the media-type of a response to be an inaccurate description of the body of the response?

似乎Spring MVC 4.1.0确实如此在进行内容协商时不遵守媒体类型参数,并给出响应的媒体类型的参数对响应主体的不准确描述的响应。这似乎是因为 org.springframework.util.MimeType.isCompatibleWith(MimeType)方法不检查 MimeType 对象。

It seems that Spring MVC 4.1.0 does not respect media-type parameters when doing content negotiation, and gives responses for which the parameters of the media-type of the response are an inaccurate description of the body of the response. This seems to be because the org.springframework.util.MimeType.isCompatibleWith(MimeType) method does not examine the parameters of the MimeType objects.

推荐答案

相关标准, RFC 7231第3.1.1.1节,关于媒体类型的说法如下:

The relevant standard, RFC 7231 section 3.1.1.1, says the following about media-types:


类型/子类型后面可以跟
name = value pairs形式的参数。

The type/subtype MAY be followed by parameters in the form of name=value pairs.

因此,接受 Content-Type 标头可能包含媒体类型参数。它补充说:

So, Accept and Content-Type headers may contain media type parameters. It adds:



参数的存在与否可能对媒体类型的处理很重要,
取决于媒体类型注册表中的定义。

The presence or absence of a parameter might be significant to the processing of a media-type, depending on its definition within the media type registry.

这表明使用参数类型的服务器代码应该注意它们,而不是简单地丢弃它们,因为对于某些媒体类型,它们显着。它必须在是否考虑媒体类型参数是否重要方面实现一些智能。

That suggests that the server code that uses parameter types should pay attention to them, and not simply discard them, because for some media types they will be significant. It has to implement some smarts in whether to consider whether the media type parameters are significant.

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消息转换器。

Spring MVC 4.1.0 therefore seems to be wrong to completely ignore the parameters when doing content negotiation: the class org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor is incorrect to use org.springframework.util.MimeType.isCompatibleWith(MimeType), or that MimeType.isCompatibleWith(MimeType) method is incorrect. If you provide Spring with several HTTP message converters that differ only in the parameters of their supported media type, Spring will not reliably choose the HTTP message converter that has the media type that exactly matches the requested media type.

3.1.1.5 ,它描述了 Content-Type 标题,它说:

In section 3.1.1.5, where it describes the Content-Type header, it says:


指示的媒体类型定义数据
格式以及收件人打算如何处理该数据

The indicated media type defines both the data format and how that data is intended to be processed by a recipient

由于媒体类型的参数通常可能会改变数据格式,因此Spring MVC 4.1.0的行为是错误的,提供的参数对响应正文的描述不准确:方法 AbstractMessageConverterMethodProcessor.getMostSpecificMediaType(MediaType,MediaType)返回<$ c是错误的$ c> acceptType 而不是 produceTypeToUse 当这两种类型具有同等特异性时。

As the parameters of a media type in general could vary the data format, the behaviour of Spring MVC 4.1.0 is wrong, in providing parameters that are an inaccurate description of the body of the response: the method AbstractMessageConverterMethodProcessor.getMostSpecificMediaType(MediaType, MediaType) is wrong to return the acceptType rather than the produceTypeToUse when the two types are equally specific.

但是,第3.4.1节,讨论内容协商(主动协商),注意:

However, section 3.4.1, which discusses content negotiation (Proactive Negotiation), notes:


用户代理不能依赖由于原始服务器可能没有为所请求的资源实施
主动协商,或者可能决定
发送的响应不符合用户代理的$ b,因此主动协商首选项的价格始终为
。 $ b首选项优于发送406(不可接受)响应。

A user agent cannot rely on proactive negotiation preferences being consistently honored, since the origin server might not implement proactive negotiation for the requested resource or might decide that sending a response that doesn't conform to the user agent's preferences is better than sending a 406 (Not Acceptable) response.

因此服务器允许的提供不完全匹配所请求的媒体类型参数的响应,作为无法提供完全匹配的后备。也就是说,它可以选择使用 application / vnd.example进行响应; version = 1 响应正文, Content-Type:application / vnd.example;版本= 1 标题,尽管请求说接受:application / vnd.example; version = 2 if,且仅当生成有效的 application / vnd.example;版本= 2 回复是不可能的。

So the server is permitted to give a response that does not exactly match the media-type parameters requested, as a fall-back when it can not provide an exact match. That is, it may choose to respond with a application/vnd.example; version=1 response body, with a Content-Type: application/vnd.example; version=1 header, despite the request saying Accept: application/vnd.example; version=2, if, and only if generating a valid application/vnd.example; version=2 response would be impossible.

这种明显错误的Spring行为已经有了Spring bug报告, SPR-10903 。 Spring开发人员将其关闭为Works as Designed,注意

This apparently incorrect behaviour of Spring already has a Spring bug report, SPR-10903. The Spring developers closed it as "Works as Designed", noting


我不知道将媒体类型与其参数有效比较的任何规则。这实际上取决于媒体类型......如果你真的试图通过媒体类型实现REST版本,似乎最常见的解决方案是使用不同的媒体类型,因为它们的格式在不同版本之间明显改变:

I don't know any rule for comparing media types with their parameters effectively. It really depends on the media type...If you're actually trying to achieve REST versioning through media types, it seems that the most common solution is to use different media types, since their format obviously changed between versions:


  • application / vnd.spring.foo.v1 + json

  • application / vnd.spring.foo.v2 + json

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

这篇关于HTTP内容协商是否遵循媒体类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆