【问题标题】:Why HttpURLConnection does not send data unless I try to receive something为什么除非我尝试接收某些东西,否则 HttpURLConnection 不发送数据
【发布时间】:2014-11-07 18:55:04
【问题描述】:

我无法理解为什么下面的代码没有将数据包放到网络上(通过 wireshark 确认)。我相信,这是一种相当标准的发送 HTTP POST 请求的方法。我不打算只看POST

private void sendRequest() throws IOException {
    String params = "param=value";
    URL url = new URL(otherUrl.toString());
    HttpURLConnection con = (HttpURLConnection)url.openConnection();
    con.setDoOutput(true);
    con.setDoInput(true);    //setting this to `false` does not help
    con.setRequestMethod("POST");
    con.setRequestProperty("Content-Type", "text/plain");
    con.setRequestProperty("Content-Length", "" + Integer.toString(params.getBytes().length));
    con.setRequestProperty("Accept", "text/plain");
    con.setUseCaches(false);
    con.connect();
    DataOutputStream wr = new DataOutputStream(con.getOutputStream());
    wr.writeBytes(params);
    wr.flush();
    wr.close();
    //Logger.getLogger("log").info("URL: "+url+", response: "+con.getResponseCode());
    con.disconnect();
}

会发生什么……实际上什么都没有,除非我尝试阅读任何内容。例如,取消注释上面读取响应代码的日志行。尝试通过con.getInputStream(); 阅读回复也可以。没有数据包的移动。当我取消注释 getResponseCode 时,我可以看到 http POST 被发送,然后 200 OK 被发送回来。顺序是正确的。 IE。在发送 POST 之前,我没有得到一些疯狂的回应。其他一切看起来完全一样(如果需要,我可以附上wireshark截图。)。在调试器中执行代码(即不会在任何地方阻塞)。

我不明白在什么情况下会发生这种情况。我相信应该可以用con.setDoInput(false); 发送POST 请求。目前它不发送任何内容或失败(尝试执行 con.getResponseCode() 时)但有一个例外,因为我显然承诺我不会阅读任何内容。

这可能是相关的,在sendRequest 之前我确实从同一个站点请求了一些数据,但我相信我正确地关闭了所有内容。即:

public static String getData(String urlAddress) throws MalformedURLException, IOException {
    URL url = new URL(urlAddress);
    HttpURLConnection con = (HttpURLConnection)url.openConnection();
    con.setDoOutput(false);
    InputStream in = con.getInputStream(); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    StringBuilder data = new StringBuilder();
    String line;
    while((line = reader.readLine()) != null) {
        data.append(line);
    }
    reader.close();
    in.close();
    con.getResponseCode();
    con.disconnect();
    return data.toString();
}

这两种情况下url的服务器是一样的,端口也是一样的,所以我相信可以使用同一个socket进行通信。上面的代码可以正常工作并正确检索数据。

我不确定,也许我没有清理某些东西,它被缓存了,所以如果没有明确的读取,POST 就会延迟。套接字上没有其他流量。

【问题讨论】:

    标签: java http httpurlconnection


    【解决方案1】:

    除非您使用固定长度或分块传输模式,否则HttpURLConnection 将缓冲您的所有输出,直到您调用getInputStream()getResponseCode(),以便它可以发送正确的 Content-length 标头。

    如果你打电话给getResponseCode(),你应该看看它的价值。

    【讨论】:

    • 即使用户手动指定内容长度标头也是如此,就像在这种情况下?
    • 是的。手动设置没有效果。 Java 总是设置它,除非在我提到的不需要它的情况下。
    • 我不认为看它的价值有什么不同。文件完成后有200 OK 消息。那么con.setDoInput(false); 的目的是什么。由于缓冲,我显然不能在这种情况下使用它。这很反直觉。我认为我的方法没有错,但我的代码不起作用。我确实知道它会被缓冲,当然应该关心响应代码。但是有一个选项,setDoInput(false)。对我来说,它要么没有意义(应该被禁止),要么不起作用。
    • 我已经描述了它是如何工作的。由你来吸收信息。 NB 您可以通过查看其值来了解是否有 200 响应的唯一方法。您的代码没有这样做。
    猜你喜欢
    • 1970-01-01
    • 2021-02-12
    • 2012-02-24
    • 2020-07-08
    • 1970-01-01
    • 2012-12-10
    • 2021-10-21
    • 2011-04-10
    • 2013-01-26
    相关资源
    最近更新 更多