Java 是'*';根据HTTP规范,内容类型的有效通配符?
我们使用的是Jax-RS的Jersey参考实现。Jersey的Jax-RS客户端实现在没有指定accept头的情况下向请求附加一个默认accept头。默认的accept标头如下所示:Java 是'*';根据HTTP规范,内容类型的有效通配符?,java,http,jax-rs,http-accept-header,Java,Http,Jax Rs,Http Accept Header,我们使用的是Jax-RS的Jersey参考实现。Jersey的Jax-RS客户端实现在没有指定accept头的情况下向请求附加一个默认accept头。默认的accept标头如下所示: Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 如您所见,它使用单个星号“*”作为内容类型(在image/jpeg之后) 在Jax-RS规范(请参阅)中,此单个*定义为 /** * The value of a type or subt
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
如您所见,它使用单个星号“*”作为内容类型(在image/jpeg之后)
在Jax-RS规范(请参阅)中,此单个*定义为
/**
* The value of a type or subtype wildcard {@value #MEDIA_TYPE_WILDCARD}.
*/
public static final String MEDIA_TYPE_WILDCARD = "*";
/**
* A {@code String} constant representing wildcard {@value #WILDCARD} media type .
*/
public final static String WILDCARD = "*/*";
我将其解释为“任何媒体类型的通配符”
“*/*”定义为
/**
* The value of a type or subtype wildcard {@value #MEDIA_TYPE_WILDCARD}.
*/
public static final String MEDIA_TYPE_WILDCARD = "*";
/**
* A {@code String} constant representing wildcard {@value #WILDCARD} media type .
*/
public final static String WILDCARD = "*/*";
我将其解释为“任何媒体范围的通配符”
但是,HTTP规范()未提及“任何媒体类型”通配符,仅提及媒体范围通配符:
media-range = ( "*/*"
/ ( type "/" "*" )
/ ( type "/" subtype )
) *( OWS ";" OWS parameter )
(..)
The asterisk "*" character is used to group media types into ranges,
with "*/*" indicating all media types and "type/*" indicating all
subtypes of that type. The media-range can include media type
parameters that are applicable to that range.
我将其解释为允许的内容类型:
- */*
- 正文/*
- 文本/纯文本
- 单个星号“*”是否为有效的内容类型(允许服务器响应任何内容类型)
- 或者使用单个星号是否会产生错误?如果是,是哪一个?
- 400坏请求
- 406不可接受
- 或者服务器应该更宽容一些,将*视为通配符*/*,尽管*不是有效的内容类型(并且可能会在日志或其他内容中产生警告)
sun.net.www.protocol.http.HttpURLConnection
static final String acceptString = "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2";
所以,如果这是一个bug,它不是Jersey的bug,而是Java的HttpURLConnection
我将其解释为“任何媒体类型的通配符”
我认为这是不正确的。它是类型或子类型的通配符。任何媒体类型的通配符都定义为*/*
,就像在HTTP规范中一样
另外,如果有疑问,请遵循HTTP规范。最后,这就是您正在使用的通信协议。另一方可能不知道Jax RS规范。Jersey客户端库/代码似乎有问题 查看以下位置的JAX-RS规范: ,我找不到任何支持媒体类型*的明确提及。它明确提及支持的媒体类型,如“n/m”,其中m可以是*或n和m可以是*,但仅*未提及 引用文件: 首先,让我们定义客户端媒体类型和服务器媒体类型 如请求中的Accept标头和@Products所示 资源方法上的注释。让客户端媒体类型 形式为n/m;q=v1,服务器媒体类型为n/m;qs=v2 以及形式为n/m;q=v1;qs=v2;d=v3的组合媒体类型,其中 下面定义了距离系数d。对于这些类型中的任何一种,m都可以是 ∗, 或者m和n可以是∗ 假设q和qs的值为 1.0如果缺席 因此,我认为Jersey客户端API有问题,它在没有提供明确的Accept头时创建默认Accept头,并将其值设置为您提到的值,即
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
另外,仅在此添加JAX-RS规范,其中提到:
(a) Filter M by removing members that do not meet the following criteria:
• The request method is supported. If no methods support the request method an implementation
MUST generate a NotAllowedException (405 status) and no entity. Note the
additional support for HEAD and OPTIONS described in Section 3.3.5.
• The media type of the request entity body (if any) is a supported input data format (see Section
3.5). If no methods support the media type of the request entity body an implementation
MUST generate a NotSupportedException (415 status) and no entity.
• At least one of the acceptable response entity body media types is a supported output data
format (see Section 3.5). If no methods support one of the acceptable response entity body
media types an implementation MUST generate a NotAcceptableException (406 status)
and no entity
因此,如果请求的媒体类型(在Accept标头中)不能与任何服务器支持的方法的响应媒体类型匹配,406 HTTP代码将是合适的
但是,在您的情况下,请求中指定了各种媒体类型,包括支持所有媒体类型的通用类型,因此抛出错误不是正确的做法,即使*不是完全正确的媒体类型。所以您说,jax rs规范是不正确的(因为它使用*作为内容类型的通配符)?@GeraldMücke是的,看起来是这样。另一方面,接下来,您可能希望接受来自客户端的
*
,并将其解释为*/*
。JAX-RS中的意图是不同的。它是目标端的匹配。这只是为了匹配传入的请求-它具有一个具体的媒体类型,例如applicationn/json-到服务端点。如果服务端点具有例如@products(“/json”),则将使用该服务端点。具有@products(“*/xml”)的服务端点显然不会。具有@products(“)的服务端点将匹配每个请求的接受。问题是,jersey客户端将请求中的*通配符内容类型发送到服务器,如果服务器端不是基于Jax-RS的rest服务怎么办?@GeraldMücke嗯,这当然取决于服务器。我怀疑这会产生严重的问题,但您必须进行彻底的测试。我认为,当您说“Jersey的Jax RS客户端实现在请求中附加了默认的accept头”时,了解您所指的是哪一个客户端是很重要的。您能澄清一下吗?我使用Jersey参考实现创建并使用了一个Jax-RS客户机。当我没有指定accept标头时,Jersey会设置默认标头(请参见此处),抛出的错误为IMHO ok,因为请求标头字段格式不正确…@JulianReschke这会使其具有限制性,并可能成为报告程序的阻止程序,因为他还指向另一个链接,其中提到开发人员很难删除默认的Accept头。此外,正如上面巴特所指出的,稳健性是这里要考虑的一个好主意:理解。我只是想指出,根据规范,这是可以的。还要记住,剧烈的错误处理有助于保持协议干净,而不会出现严重的互操作问题。请参阅XML或HTTP/2.Update