获取原始HTTP响应标头

有没有办法获得原始响应http标头?

getHeaderField()方法对我不起作用,因为服务器吐出多个“Set-Cookie”,其中一些会丢失。

getHeaderField()方法对我不起作用

你在java.net.URLConnection的上下文中问这个,是吗? 不,使用URLconnection无法获取原始HTTP响应头。 你需要回到低级别的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) {} } } } 

为了避免每个人尝试这个片段而导致SO过载,这里的输出如下:

 HTTP / 1.1 200好的
缓存控制:私有
 Content-Type:text / html; 字符集= utf-8的
到期日:2010年2月21日星期日20:39:08 GMT
服务器:Microsoft-IIS / 7.5
日期:太阳,2010年2月21日20:39:07 GMT
连接:关闭
内容长度:208969

要了解有关以低级方式发送HTTP请求的更多信息,请阅读HTTP规范 。

但是,您可能希望使用getHeaderFields()方法来检索具有多个值的标头。 getHeaderField()仅返回最后一个值,根据链接的API doc。

 List cookies = connection.getHeaderFields().get("Set-Cookie"); 

不完全’原始’但简洁:

 for (Map.Entry> k : myHttpURLConnection.getHeaderFields().entrySet()) { System.out.println(k.toString()); } 

如果您担心某些标题丢失,请使用:

 for (Map.Entry> k : myHttpURLConnection.getHeaderFields().entrySet()) { for (String v : k.getValue()){ System.out.println(k.getKey() + ":" + v); } } 

PS:迟到总比没有好。 🙂

简单的方法是使用URLConnectiongetHeaderFields()方法。 这是一些做同等事情的代码。

 static String[] getHeaders(HttpURLConnection con, String header) { List values = new ArrayList(); 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()]); } 

迟到了,但这是最简单的解决方案。 只需实现CookieStore。 (或使用默认实现,并让它负责将cookie添加到您的后续调用中。)

http://docs.oracle.com/javase/7/docs/api/java/net/CookieStore.html

将您的cookie存储区设置为默认cookie管理器

 CookieManager cookieManager = new CookieManager(new MyCookieStore(), CookiePolicy.ACCEPT_ALL); CookieHandler.setDefault(cookieManager); 

每个新的cookie都会在你的CookieStore中的add()中出现。 通过在单个请求中使用相同名称“Set-Cookie”覆盖params,我遇到了同样的问题,现在我同时获得了cookie和sessionId。