java - 为什么 HttpURLConnection 不发送数据,除非我尝试接收一些东西

标签 java http httpurlconnection

我无法理解为什么以下代码没有将数据包放到线路上(通过 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() 时)并出现异常,因为我显然 promise 我不会读取任何内容。

这可能是相关的,在 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 的服务器是相同的,端口也是,所以我相信可以使用相同的套接字进行通信。上面的代码可以正常工作并正确检索数据。

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

最佳答案

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

如果您调用 getResponseCode(),您应该查看它的值。

关于java - 为什么 HttpURLConnection 不发送数据,除非我尝试接收一些东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26808136/

相关文章:

java - 降低圈复杂度的最佳方法

java - 谷歌地图教程 : What is Context?

http - URL "scheme plus authority"的正式名称

java - 如何提高通过 HttpURLConnection 下载时的下载速度?

java - 使用 StringTokenizer 获取单词

http - 为什么 CORS 规范不允许重定向?

http - 最大 HTTP 数据包大小

java - 在 HttpURLConnection 中设置 setChunkedStreamingMode 向服务器发送数据失败

java - 即使使用错误的 http 代码 403、404 等,也可以使用 HttpUrlConnection 检索数据

java - 德摩根定律