5

使用 Javajava.net.HttpURLConnection有一个getResponseMessage()方法来检索任何Reason-Phrase文本(由RFC2616 6.1 状态行指定)。

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

有没有办法使用此 API 获取在状态行末尾返回的文本?如果没有,为什么不包括在内?(我知道 HTTP 2没有定义这个值,但大多数应用程序仍然使用 HTTP 1.1,它仍然有效。)

4

3 回答 3

5

有没有办法使用此 API 获取在状态行末尾返回的文本?

不。

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

由于详细的设计原理尚未公布,我们无法告诉您实际原因。

但是,我想原因/推理是这样的:

  1. 因为客户通常会忽略文本。(忍受我...)

  2. 因为文本很少包含任何有用的东西。它通常只是对应于响应代码的标准(推荐)文本消息。(这是客户经常忽略文本的原因之一。

  3. 因为如果 Web 应用程序要提供有意义的解释,它很可能会在有效负载中进行。(因为1。但也加强了它。)

  4. 因为一些网络堆栈不让网络应用程序设置原因文本。

  5. 因为一些 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 现在正在筹备中。没有人能看到足够远的未来来准确预测在(比如说)5 年内有多少 Web 服务器将使用什么版本的 HTTP。

1 - 服务器端采用率呈上升趋势,但因服务器平台而异。有关一些数据点,请参阅2020 年网络年鉴


鉴于上述情况,如果您让您的客户端代码依赖于查看特定原因文本......或者根本没有看到任何......那么它可能会破坏某些 Web 服务器。

因此,我想说 Java 11 的 HttpClient API 设计者帮了我们一个大忙,没有将原因文本暴露给客户端代码。

您可以不同意……并使用其他 HTTP 客户端库。


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

于 2020-08-25T10:19:38.650 回答
1

我正在寻找 Java 中的 http 状态代码原因短语,并在我的 Google 搜索中发现了这个讨论。我最终编写了自己的函数,我想分享它以防其他人发现它有用。它可能不完整,但它符合我的目的。

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 "";
    }
}
于 2021-05-25T06:03:59.447 回答
0

正如您注意到的HttpResponse那样,它没有提供任何 API 来获取原因短语。没有隐藏的方法来获得它。您是否有一个用例,其中使用原因短语 in 的访问器HttpResponse会很有用?

于 2020-08-25T09:19:51.170 回答