Java 为什么URLConnection.getInputStream()不包含HTTP响应头?

Java 为什么URLConnection.getInputStream()不包含HTTP响应头?,java,http,jakarta-ee,java-io,Java,Http,Jakarta Ee,Java Io,我用这个 public static final String LOGIN_URL = "http://www.icourse163.org/passport/reg/icourseLogin.do"; public static void loginSimulation() throws IOException { URL loginUrl = new URL(LOGIN_URL); URLConnection connection = loginUrl.openConnec

我用这个

public static final String LOGIN_URL = "http://www.icourse163.org/passport/reg/icourseLogin.do";

public static void loginSimulation() throws IOException {
    URL loginUrl = new URL(LOGIN_URL);
    URLConnection connection = loginUrl.openConnection();
    connection.setRequestProperty("User-Agent",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36");
    connection.setRequestProperty("Accept",
            "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
    connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
    connection.setRequestProperty("Connection", "keep-alive");
    connection.setRequestProperty("Referer", "http://www.icourse163.org/member/logout.htm");
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    connection.setDoOutput(true);

    PrintWriter loginDataWriter = new PrintWriter(connection.getOutputStream());

    String loginData = "returnUrl=aHR0cDovL2ljb3Vyc2UxNjMub3JnLw%3D%3D&failUrl=aHR0cDovL3d3dy5pY291cnNlMTYzLm9yZy9tZW1iZXIvbG9naW4uaHRtP2VtYWlsRW5jb2RlZD1PVGM1TnpJME9EZ3lRSEZ4TG1OdmJRPT0%3D&savelogin=false&oauthType=&username=979724882%40qq.com";
    loginDataWriter.print(loginData);
    loginDataWriter.flush();



    BufferedReader reader = new BufferedReader(
            new InputStreamReader(connection.getInputStream()));
    StringBuilder builder = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null){
        builder.append(line);
    }

但是
builder.toString
没有任何关于响应头的信息?我认为在我的客户机和服务器之间有一个管道。所以所有的响应都应该通过这个管道(包括响应头、响应内容等)。但结果并非如此。为什么?

无论
连接的类型是什么(
HttpUrlConnection
URLConnection
等),它都将提供头的访问器。查看名为
*.eaders.*
的方法,例如:
getHeaderFields()

相反,
getInputStream()
可能只读取响应体

编辑1:根据您更新的问题,很明显您正在使用
java.net.URLConnection
,因此我的原始答案是:
getInputStream()
只读取响应正文,您将从
getHeaderFields()
获取HTTP响应头


修改后的问题还表明,您不仅对如何获取标题感兴趣,而且对为什么输入流中没有标题感兴趣。在您的客户端和原始HTTP响应之间有一个库,该库决定以以下方式向您呈现原始响应:(1)响应体作为
InputStream
;(2) 标题显示为
映射
。这是在实现该库时做出的选择。因此,只要使用
java.net.URLConnection
,就必须使用响应。FWIW,其他库(如ApacheCommons的HttpClient)也做了同样的事情。

无论
连接的类型是什么(
HttpUrlConnection
URLConnection
等),它都将提供头的访问器。查看名为
*.eaders.*
的方法,例如:
getHeaderFields()

相反,
getInputStream()
可能只读取响应体

编辑1:根据您更新的问题,很明显您正在使用
java.net.URLConnection
,因此我的原始答案是:
getInputStream()
只读取响应正文,您将从
getHeaderFields()
获取HTTP响应头


修改后的问题还表明,您不仅对如何获取标题感兴趣,而且对为什么输入流中没有标题感兴趣。在您的客户端和原始HTTP响应之间有一个库,该库决定以以下方式向您呈现原始响应:(1)响应体作为
InputStream
;(2) 标题显示为
映射
。这是在实现该库时做出的选择。因此,只要使用
java.net.URLConnection
,就必须使用响应。FWIW,其他库(如Apache Commons的HttpClient)也做了同样的事情。

您应该使用getHeaderFields来获取响应头。

您应该使用getHeaderFields来获取响应头。

您可以这样尝试吗

import java.net.*;
import java.io.*;

public class URLConnectionReader {
public static void main(String[] args) throws Exception {
    URL oracle = new URL("http://www.oracle.com/");
    URLConnection yc = oracle.openConnection();
    BufferedReader in = new BufferedReader(new InputStreamReader(
                                yc.getInputStream()));
    String inputLine;
    while ((inputLine = in.readLine()) != null) 
        System.out.println(inputLine);
    in.close();
    }

}

你能这样试试吗

import java.net.*;
import java.io.*;

public class URLConnectionReader {
public static void main(String[] args) throws Exception {
    URL oracle = new URL("http://www.oracle.com/");
    URLConnection yc = oracle.openConnection();
    BufferedReader in = new BufferedReader(new InputStreamReader(
                                yc.getInputStream()));
    String inputLine;
    while ((inputLine = in.readLine()) != null) 
        System.out.println(inputLine);
    in.close();
    }

}

我想你会发现,
连接
已经获得了所有的标题信息。可能的重复可以告诉我们什么是
连接
,即它是完全限定的类名吗?@SteveSmith我认为错了吗?我认为HTTP过程是客户端通过连接向服务器发送请求头,服务器向客户端发送响应?因此connection.getInputStream应该拥有所有响应数据(包括响应头、响应内容等)
URLConnection
自动读取所有头(它需要它们知道该做什么)
getInputStream()
仅用于读取“正文”,例如HTML或其他内容。我想您会发现
连接
已经获得了所有标题信息。可能的重复项您能告诉我们
连接
是什么,即它是完全限定的类名吗?@SteveSmith我想错了吗?我认为HTTP过程是客户端通过连接向服务器发送请求头,服务器向客户端发送响应?因此connection.getInputStream应该拥有所有响应数据(包括响应头、响应内容等)
URLConnection
自动读取所有头(它需要它们知道该做什么)
getInputStream()
仅用于读取“正文”,例如HTML或其他内容。我认为HTTP过程是客户端通过连接向服务器发送请求头,服务器向客户端发送响应?因此connection.getInputStream应该包含所有响应数据(包括响应头、响应内容等)…您的代码没有返回任何响应头。因此响应头没有在客户端和服务器之间使用pip?conn.getHeaderField(“CustomHeader”)返回响应头,而不是请求头。要返回请求头,请使用:conn.getRequestProperty(“CustomHeader”),我认为HTTP过程是客户端通过连接向服务器发送请求头,服务器向客户端发送响应?因此connection.getInputStream应该包含所有响应数据(包括响应头、响应内容等)…您的代码没有返回任何响应头。因此响应头没有在客户端和服务器之间使用pip?conn.getHeaderField(“CustomHeader”)返回响应头,而不是请求头。要返回请求头,请使用:conn.getRequestProperty(“CustomHeader”)您似乎是对的。我只是有点困惑…我只是认为所有响应数据都可以通过
连接获得。getInputStream
。因为