[英]How do I get the http status message from responses on java.net.HttpClient requests
一些 http 服务器会生成带有状态代码和自定义状态消息的响应。 当使用 java HttpURLConnection
class 发出请求时,可以访问此消息。 但是,使用最近的java.net.HttpClient
样式 api 我似乎无法找到访问消息本身的方法。 我只能找到一种获取状态码的方法。
为了说明这种情况,请考虑以下代码:
/**
* Stand in replacement for a server which puts a custom message in the http status.
* Blindly sends a fixed http response on every connection in receives, irrespective
* of protocol or context.
*/
public class ExampleServer {
private static final int port = 8080;
private static final byte [] fixed_response = String.join ("\n",
"HTTP/1.1 403 Missing X-Api-Key header",
"Content-Length: 12",
"",
"Unauthorized"
).getBytes(StandardCharsets.UTF_8);
public static void main (String [] args) throws Exception {
ServerSocket server = new ServerSocket (port);
ExecutorService executor = Executors.newCachedThreadPool ();
while ( true ) {
Socket socket = server.accept ();
executor.submit (() -> {
socket.getOutputStream ().write (fixed_response);
socket.close ();
return null;
});
}
}
}
我们可以使用HttpURLConnection
方法显示状态。
URI uri = URI.create ("http://localhost:" + port + "/any/path");
HttpURLConnection connection = (HttpURLConnection) uri.toURL ().openConnection ();
connection.setRequestMethod ("GET");
System.out.println ("status: " + connection.getResponseCode () + " " + connection.getResponseMessage ());
System.out.println ("body : " + new String (connection.getErrorStream ().readAllBytes ()));
在以下场景中,我将如何创建相同的 output?
HttpClient client = HttpClient.newHttpClient ();
HttpRequest request = HttpRequest.newBuilder ()
.uri (URI.create ("http://localhost:" + port + "/any/path"))
.GET ().build ();
HttpResponse<String> response = client.send (request, HttpResponse.BodyHandlers.ofString ());
System.out.println ("status: " + response.statusCode () + " " /* what goes here? */);
System.out.println ("body : " + response.body ());
“原因短语”真的无关紧要,在 HTTP/2 和 HTTP/3 中不再存在。 我不会在这方面付出太多努力。
正如 Julian 所说,这个原因在 HTTP/2 中不再存在。 虽然,如果您确实需要获取给定状态代码的名称,您可以使用Map
将数字与名称匹配。
这是使用MDN名称的代码的 Map 代码。
import java.util.Map;
import static java.util.Map.entry;
public class HttpStatusReasons {
private static final String UNKNOWN_STATUS = "Unknown Status";
private static final Map<Integer, String> REASONS = Map.ofEntries(
// informational
entry(100, "Continue"),
entry(101, "Switching Protocol"),
entry(102, "Processing"),
entry(103, "Early Hints"),
// successful
entry(200, "OK"),
entry(201, "Created"),
entry(202, "Accepted"),
entry(203, "Non-Authoritative Information"),
entry(204, "No Content"),
entry(205, "Reset Content"),
entry(206, "Partial Content"),
entry(207, "Multi Status"),
entry(208, "Already Reported"),
entry(226, "IM Used"),
// redirection
entry(300, "Multiple Choice"),
entry(301, "Moved Permanently"),
entry(302, "Found"),
entry(303, "See Other"),
entry(304, "Not Modified"),
entry(305, "Use Proxy"), // deprecated
entry(307, "Temporary Redirect"),
entry(308, "Permanent Redirect"),
// client error
entry(400, "Bad Request"),
entry(401, "Unauthorized"),
entry(402, "Payment Required"),
entry(403, "Forbidden"),
entry(404, "Not Found"),
entry(405, "Method Not Allowed"),
entry(406, "Not Acceptable"),
entry(407, "Proxy Authentication Required"),
entry(408, "Request Timeout"),
entry(409, "Conflict"),
entry(410, "Gone"),
entry(411, "Length Required"),
entry(412, "Precondition Failed"),
entry(413, "Payload Too Long"),
entry(414, "URI Too Long"),
entry(415, "Unsupported Media Type"),
entry(416, "Range Not Satisfiable"),
entry(417, "Expectation Failed"),
entry(418, "I'm a Teapot"),
entry(421, "Misdirected Request"),
entry(422, "Unprocessable Entity"),
entry(423, "Locked"),
entry(424, "Failed Dependency"),
entry(425, "Too Early"),
entry(426, "Upgrade Required"),
entry(428, "Precondition Required"),
entry(429, "Too Many Requests"),
entry(431, "Request Header Fields Too Large"),
entry(451, "Unavailable for Legal Reasons"),
// server error
entry(500, "Internal Server Error"),
entry(501, "Not Implemented"),
entry(502, "Bad Gateway"),
entry(503, "Service Unavailable"),
entry(504, "Gateway Timeout"),
entry(505, "HTTP Version Not Supported"),
entry(506, "Variant Also Negotiates"),
entry(507, "Insufficient Storage"),
entry(508, "Loop Detected"),
entry(510, "Not Extended"),
entry(511, "Network Authentication Required")
);
public static String getReasonForStatus(int status) {
return REASONS.getOrDefault(status, UNKNOWN_STATUS);
}
}
如果您使用 spring ,您可以使用来自 org.springframework.http.HttpStatus 的 HttpStatus ,如下所示:
HttpStatus.valueOf(connection.getResponseCode()).getReasonPhrase()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.