【发布时间】:2018-11-21 09:24:22
【问题描述】:
我们正在使用 Jax-RS 的 Jersey 参考实现。如果未指定接受标头,Jersey 的 Jax-RS 客户端实现将默认接受标头附加到请求中。默认的接受标头如下所示:
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
如您所见,它使用单个星号“*”作为内容类型(在 image/jpeg 之后)。
在 Jax-RS 规范中(参见 here),这个单个 * 被定义为
/**
* 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 规范 (RFC7231) 没有提到“任何媒体类型”通配符,只有媒体范围通配符:
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.
我将其解释为允许的内容类型:
- */*
- 文本/*
- 文本/纯文本
换句话说,内容类型必须始终为“某事斜线某事”或“单个 * 不是有效的内容类型”形式。虽然,后者没有明确说明。
现在这两个规范都是公开标准化的,HTTP 规范在某种程度上是 Jax-RS 规范的父文档,因为 Jax-RS 基于 HTTP。恕我直言,这两个标准在通配符内容类型方面相互矛盾。
问题是,什么是适用的?
- 单个星号“*”是否是有效的内容类型(允许服务器以任何内容类型进行响应)
- 还是应该使用单个星号产生错误?如果是,是哪一个?
- 400 错误请求
- 406 不可接受
- 或者服务器是否应该更加宽容,并将 * 视为通配符 */* 尽管 * 不是有效的内容类型(并且可能在日志中产生警告或其他内容)?
编辑
在处理 Jsoup(不是 JaxRS/Jersey)时,我观察到 JSoup 使用相同的默认接受类型,而且似乎默认标头是 sun.net.www.protocol.http.HttpURLConnection 的实现细节
static final String acceptString = "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2";
所以如果这是一个错误,那不是 Jersey 的错误,而是 Java 的 HttpURLConnection
【问题讨论】:
-
我认为当您说“Jersey 的 Jax-RS 客户端实现将默认接受标头附加到请求”时,了解您指的是哪个客户端很重要。你能澄清一下吗?
-
我使用 Jersey 参考实现创建并使用了一个 Jax-RS 客户端。当我没有指定接受标头时,Jersey 会设置默认标头(请参阅此处stackoverflow.com/questions/40900870/…)
标签: java http jax-rs http-accept-header