获取原始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:迟到总比没有好。 🙂
简单的方法是使用URLConnection
的getHeaderFields()
方法。 这是一些做同等事情的代码。
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。