Java 获取原始HTTP响应头

Java 获取原始HTTP响应头,java,http,header,Java,Http,Header,有没有办法获取原始响应http头 getHeaderField()方法对我不起作用,因为服务器吐出多个“Set Cookie”,其中一些会丢失 getHeaderField()方法对我不起作用 你问这个问题的背景是,是吗?否,使用URLconnection无法获取原始HTTP响应头。您需要回到低级编程。这里有一个,只是复制粘贴运行它 package com.stackoverflow.q2307291; import java.io.BufferedReader; import java.io

有没有办法获取原始响应http头

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

getHeaderField()
方法对我不起作用

你问这个问题的背景是,是吗?否,使用
URLconnection
无法获取原始HTTP响应头。您需要回到低级编程。这里有一个,只是复制粘贴运行它

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) {} 
        }
    }

}
为了避免每个人都在尝试此代码段时过载,以下是输出的样子:

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
简单的方法是使用
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()]);
}
static String[]getHeaders(HttpURLConnection-con,String-header){
列表值=新的ArrayList();
intIDX=(con.getHeaderFieldKey(0)=null)?1:0;
while(true){
字符串键=con.getHeaderFieldKey(idx);
if(key==null)
打破
if(标题等信号案例(关键))
add(con.getHeaderField(idx));
++idx;
}
返回values.toArray(新字符串[values.size()]);
}

不完全是“原始”而是简洁:

for (Map.Entry<String, List<String>> k : myHttpURLConnection.getHeaderFields().entrySet()) {
    System.out.println(k.toString());
}
for(Map.Entry k:myHttpURLConnection.getHeaderFields().entrySet()){
System.out.println(k.toString());
}
如果您担心某些标题会丢失,请执行以下操作:

for (Map.Entry<String, List<String>> k : myHttpURLConnection.getHeaderFields().entrySet()) {
    for (String v : k.getValue()){
         System.out.println(k.getKey() + ":" + v);
    }
}
for(Map.Entry k:myHttpURLConnection.getHeaderFields().entrySet()){
for(字符串v:k.getValue()){
System.out.println(k.getKey()+“:”+v);
}
}

附:迟做总比不做强。:)

派对迟到了,但这里有最简单的解决办法。只要实现CookieStore。(或者使用默认实现,让它负责将cookie添加到后续调用中。)

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

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

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

听起来您在使用类似Apache HTTP客户端的库?如果是这样的话,我想你会问这个特定的库是否有这样一个方法。这会很有帮助,但我认为他使用的不是apache客户端而是Java标准库:Heys,你是说
Java.net.URLConnection
是建立在这些方法之上的吗?“使用
URLConnection
无法获取原始HTTP响应头”?什么是
getHeaderField(int)
return?@erickson:它解析原始响应头并返回给定索引上的头的值。它没有完全按照我的答案中的引号返回原始响应头。我相信你在这个问题的上下文中误解了“raw”。顺便问一下,你读过
getHeaderFields()了吗
我的答案底部有提示吗?顺便说一句:我没有否决你的答案:)我看不出“原始”值有什么不同。你能举个例子说明“原始”值“值与通过
URLConnection
API返回的值不同?@erickson:获得的值没有差异。Raw只是指未解析的、普通的,正如我在回答中引用的输出所示。OP很可能打算进一步手动解析它,以便检索多个值。@Pacerier您尝试过吗?您发现什么不正确?我得到的是空的
Set Cookie
标题。两到三个,取决于对方发送的内容。其他标题工作正常。问题似乎并不在于打印为
connection.getRequestProperties()
显示
设置cookie=[,]
。cookies是
安全的;HTTPOnly
,但这在Java中并不重要。奇怪,不是吗?我没有测试您的示例,但我相信getHeaderFields只为字段返回一个值。如果您得到多个名称相同的字段,例如“Set Cookies”就是其中之一,这会导致问题。@p4553d-这就是entrySet返回列表作为值的原因。。。我想。
CookieManager cookieManager = new CookieManager(new MyCookieStore(), CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);