Java 获取原始 HTTP 响应标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2307291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting raw HTTP response headers
提问by p4553d
Is there any way to get raw response http header?
有没有办法获得原始响应http标头?
The getHeaderField()
method doesn't work for me, because server spits multiple 'Set-Cookie' and some of them get lost.
该getHeaderField()
方法对我不起作用,因为服务器吐出多个“Set-Cookie”并且其中一些丢失了。
采纳答案by BalusC
The
getHeaderField()
method doesn't work for me
该
getHeaderField()
方法对我不起作用
You're asking this in the context of java.net.URLConnection
, is it? No, obtaining the raw HTTP response headers is not possible with URLconnection
. You'll need to fall back to low-level Socketprogramming. Here's an SSCCE, just copy'n'paste'n'run it.
你是在上下文中问这个的java.net.URLConnection
,是吗?不,使用URLconnection
. 您需要回退到低级Socket编程。这是一个SSCCE,只需复制'n'paste'n'run它。
package com.stackoverflow.q2307291;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class Test {
public static void main(String[] args) throws IOException {
String hostname = "stackoverflow.com";
int port = 80;
Socket socket = null;
PrintWriter writer = null;
BufferedReader reader = null;
try {
socket = new Socket(hostname, port);
writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.println("GET / HTTP/1.1");
writer.println("Host: " + hostname);
writer.println("Accept: */*");
writer.println("User-Agent: Java"); // Be honest.
writer.println(""); // Important, else the server will expect that there's more into the request.
writer.flush();
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
for (String line; (line = reader.readLine()) != null;) {
if (line.isEmpty()) break; // Stop when headers are completed. We're not interested in all the HTML.
System.out.println(line);
}
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
if (writer != null) { writer.close(); }
if (socket != null) try { socket.close(); } catch (IOException logOrIgnore) {}
}
}
}
To avoid SO being overloaded by everyone trying this snippet, here's how the output will look like:
为避免尝试此代码段的每个人都使 SO 过载,输出将如下所示:
HTTP/1.1 200 OK Cache-Control: private Content-Type: text/html; charset=utf-8 Expires: Sun, 21 Feb 2010 20:39:08 GMT Server: Microsoft-IIS/7.5 Date: Sun, 21 Feb 2010 20:39:07 GMT Connection: close Content-Length: 208969
To learn more about sending HTTP requests the low-level way, read the HTTP specification.
要了解有关以低级方式发送 HTTP 请求的更多信息,请阅读HTTP 规范。
However, you probably want to make use of getHeaderFields()
method instead to retrieve a header with multiple values. The getHeaderField()
namely only returns the last value, as per the linked API doc.
但是,您可能希望使用getHeaderFields()
method 来检索具有多个值的标头。根据getHeaderField()
链接的 API 文档,即仅返回最后一个值。
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
回答by erickson
The easy way is to use the getHeaderFields()
method of URLConnection
. Here is some code that does something equivalent.
最简单的方法是使用 的getHeaderFields()
方法URLConnection
。这是一些执行等效操作的代码。
static String[] getHeaders(HttpURLConnection con, String header) {
List<String> values = new ArrayList<String>();
int idx = (con.getHeaderFieldKey(0) == null) ? 1 : 0;
while (true) {
String key = con.getHeaderFieldKey(idx);
if (key == null)
break;
if (header.equalsIgnoreCase(key))
values.add(con.getHeaderField(idx));
++idx;
}
return values.toArray(new String[values.size()]);
}
回答by ostergaard
Not exactly 'raw' but concise:
不完全是“原始”但简洁:
for (Map.Entry<String, List<String>> k : myHttpURLConnection.getHeaderFields().entrySet()) {
System.out.println(k.toString());
}
IF you worry that some of the headers are getting lost use:
如果您担心某些标题会丢失,请使用:
for (Map.Entry<String, List<String>> k : myHttpURLConnection.getHeaderFields().entrySet()) {
for (String v : k.getValue()){
System.out.println(k.getKey() + ":" + v);
}
}
PS: Better late than never. :)
PS:迟到总比不到好。:)
回答by accordionfolder
Late to the party, but here's the simplest solution. Just implement CookieStore. (or use the default implementation and let it take care of adding the cookies to your subsequent calls.)
聚会迟到了,但这是最简单的解决方案。只需实现 CookieStore。(或使用默认实现并让它负责将 cookie 添加到您的后续调用中。)
http://docs.oracle.com/javase/7/docs/api/java/net/CookieStore.html
http://docs.oracle.com/javase/7/docs/api/java/net/CookieStore.html
Set your cookie store as the default cookie manager
将您的 cookie 存储设置为默认 cookie 管理器
CookieManager cookieManager = new CookieManager(new MyCookieStore(), CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);
And every new cookie will appear to you in add() in your CookieStore. I had the same problem with params being overwritten by having the same name "Set-Cookie" in a single request, and now I get both the cookie and the sessionId.
每一个新的 cookie 都会在你的 CookieStore 中的 add() 中出现。我在单个请求中使用相同的名称“Set-Cookie”覆盖参数时遇到了同样的问题,现在我同时获得了 cookie 和 sessionId。