Java 11的HttpClient是否有一种方法可以获取HTTP 1.1响应状态行中的Reason-Phrase?

6

使用Java的java.net.HttpURLConnection,可以使用getResponseMessage()方法检索任何Reason-Phrase文本(如RFC2616 6.1状态行中所指定的)。

在较新的Java 11 HttpClient中,java.net.http.HttpResponse仅具有statusCode()方法。

是否有一种方法可以使用此API获取状态行末尾返回的文本?如果没有,为什么没有包括它?(我知道HTTP 2 未定义此值,但大多数应用程序仍使用HTTP 1.1,其中它仍然有效。)

3个回答

7

使用此API获取状态行末尾返回的文本有什么方法吗?

没有。

如果没有,为什么没有包含在内?

我们无法告诉您实际原因,因为详细的设计理念尚未发布。

然而,我想原因可能是这样的:

由于客户通常会忽略文本。(请耐心等待...) 因为文本很少包含有用的内容。它通常只是响应代码对应的标准(推荐)文本消息。(这是文本经常被客户忽略的原因之一。) 因为如果一个Web应用程序要提供有意义的解释,它很可能会在有效载荷中进行。(因为1. 但也加强了这一点。) 因为有些Web堆栈不允许Web应用程序设置原因文本。 因为一些HTTP 1.1 Web服务器通常完全省略原因文本!(例如,在Tomcat 8.0.x中没有消息,在Tomcat 8.5.x中有启用它的选项。)
(我知道HTTP 2没有定义这个值,但大多数应用程序仍在使用HTTP 1.1,其中它仍然有效。)
那现在就是...1
这实际上是新的Web应用程序不尝试通过原因文本传递有用信息并且不支持API中的原因文本的另一个原因。
最终,大多数应用程序将使用HTTP 2或更高版本。或者至少足够多的应用程序会使用它,以至于依赖于对HTTP 1.x特性的良好支持可能会导致您的应用程序出现问题。
请记住,HTTP 3现在正在进行中。没有人能够看得太远,准确预测Web服务器将在5年内使用哪些版本的HTTP的比例。 1-服务器端采用率呈上升趋势,但具体取决于服务器平台。请参阅2020 Web Almanac了解一些数据点。
鉴于上述情况,如果您让客户端代码依赖于查看特定原因文本...或根本不查看...那么它可能会在某些Web服务器上出现故障。
因此,我认为Java 11的HttpClient API设计者们通过不向客户端代码公开原因文本给我们所有人带来了巨大的好处。
您可以自由地持不同意见...并使用其他HTTP客户端库。

我的建议是顺其自然。如果你不尝试使用理由文本(客户端或服务器端),那么你就不必处理使用它会带来的问题。问题只会变得更糟。


所有的好理由都可以解释这个决定。很不幸,规范支持是有选择性的,而之前是包括在内的。现在Java正在更快地发展并更好地传达弃用信息,这将很容易地包含在内,以便平滑迁移,并在使用减少时/如果后期删除。我想这很难评估...因为有很多私人服务存在。 - Nathan Williams
“对于曾经被包含的东西,现在规范支持是有选择性的,这仍然是不幸的。” - 这是一种观点。我认为这是一件好事。“现在Java发展更快,沟通废弃信息也更好了,这本来很容易包含进去以平滑迁移,并在使用减少时/如果后期删除。我猜很难评估...因为有很多私有服务存在。” - 我们正在谈论一个全新的API。旧的Java SE API仍然存在,据我所知,没有废弃的讨论。 - Stephen C
正在使用旧API并且在理由文本上进行(非微不足道的)使用的人将被困在HTTP 1.x上。看起来HttpUrlConnection等不太可能支持HTTP 2。请阅读JEP 110。我的看法是,他们认为HttpUrlConnection是遗留问题...就像旧的Java日期/时间和java.io.File一样。 - Stephen C

1
我在查找Java中的HTTP状态码原因短语时,在谷歌搜索中发现了这个讨论。最终,我编写了自己的函数,并希望与其他人分享,以便有需要的人可以使用它。它可能不完整,但对我的目的很有用。
public static String getReasonPhrase(int statusCode) {
    switch(statusCode) {
        case (200): return "OK";
        case (201): return "Created";
        case (202): return "Accepted";
        case (203): return "Non Authoritative Information";
        case (204): return "No Content";
        case (205): return "Reset Content";
        case (206): return "Partial Content";
        case (207): return "Partial Update OK";
        case (300): return "Mutliple Choices";
        case (301): return "Moved Permanently";
        case (302): return "Moved Temporarily";
        case (303): return "See Other";
        case (304): return "Not Modified";
        case (305): return "Use Proxy";
        case (307): return "Temporary Redirect";
        case (400): return "Bad Request";
        case (401): return "Unauthorized";
        case (402): return "Payment Required";
        case (403): return "Forbidden";
        case (404): return "Not Found";
        case (405): return "Method Not Allowed";
        case (406): return "Not Acceptable";
        case (407): return "Proxy Authentication Required";
        case (408): return "Request Timeout";
        case (409): return "Conflict";
        case (410): return "Gone";
        case (411): return "Length Required";
        case (412): return "Precondition Failed";
        case (413): return "Request Entity Too Large";
        case (414): return "Request-URI Too Long";
        case (415): return "Unsupported Media Type";
        case (416): return "Requested Range Not Satisfiable";
        case (417): return "Expectation Failed";
        case (418): return "Reauthentication Required";
        case (419): return "Proxy Reauthentication Required";
        case (422): return "Unprocessable Entity";
        case (423): return "Locked";
        case (424): return "Failed Dependency";
        case (500): return "Server Error";
        case (501): return "Not Implemented";
        case (502): return "Bad Gateway";
        case (503): return "Service Unavailable";
        case (504): return "Gateway Timeout";
        case (505): return "HTTP Version Not Supported";
        case (507): return "Insufficient Storage";
        default: return "";
    }
}

0

正如您所注意到的,HttpResponse并没有提供任何获取原因短语的API。 没有隐藏的方法可以获取它。 您是否有使用案例需要在HttpResponse中具有原因短语的访问器?


1
通常最简单的方法是使用扩展状态码来传达错误文本。与仅使用规范提供的插槽相比,为短消息协商有效载荷格式需要更多的工作。 - Nathan Williams
你可以使用不可变的静态哈希映射(或 switch 语句)将状态码映射到其标准原因短语。 - daniel
重点是服务器可能在原因短语中表达独特的细节,而预设的映射不会反映这些内容。例如:https://dev59.com/3m025IYBdhLWcg3wQDdb#6123801 这是一个随着HTTP 2采用而逐渐减少的模式,但它今天仍在使用中。 - Nathan Williams
你经常遇到这种情况吗?我期望响应体包含详细信息。 - daniel
我已经在简单服务中使用过它。无法知道它在实际应用中有多常见。它仍然是servlet规范的一部分,因此客户端API决策存在一些不对称性(尽管这些内容不像以前那么庞大)。 - Nathan Williams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接