有没有一种方法可以使用Java 11的HttpClient从HTTP 1.1响应的状态行中提取原因短语?

问题描述

对于Java的java.net.HttpURLConnection,有一种getResponseMessage()方法可检索任何Reason-Phrase文本(由RFC2616 6.1 Status Line指定)。

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

是否可以使用此API获取状态行末尾返回的文本?如果没有,为什么不包括在内? (我知道HTTP 2 does not define这个值,但是大多数应用程序仍然使用HTTP 1.1保持有效。)

解决方法

是否可以使用此API获取状态行末尾返回的文本?

否。

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

  1. 因为客户端通常会忽略文本。 (和我在一起...)

  2. 因为文本很少包含有用的内容。通常,它只是与响应代码相对应的标准(推荐)文本消息。 (被忽略的原因之一)

  3. 因为如果Web应用程序将提供有意义的解释,则很可能会在有效负载中执行此操作。 (因为1。而且还要加强它。)

  4. 因为某些Web堆栈不允许Web应用设置原因文本。

  5. 因为某些HTTP 1.1 Web服务器通常完全将原因文本排除在外! (例如,对于Tomcat 8.0.x,没有消息,而对于Tomcat 8.5.x,则有启用它的选项。)


(我知道HTTP 2并未定义该值,但是大多数应用程序仍然在有效的地方使用HTTP 1.1。)

这实际上是(新)Web应用程序不尝试以文本形式传递有用信息并且不支持API的另一个原因。


鉴于上述情况,如果您使客户端代码依赖于查看特定的原因文本……或完全看不到任何……那么某些Web服务器很可能会中断。

因此,我想说Java 11的HttpClient API设计人员通过不将原因文本公开给客户端代码而对我们所有人都大有帮助

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


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

,

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

,

我正在寻找 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 "";
    }
}