Java 为什么HttpURLConnection不发送数据,除非我尝试接收某些内容

Java 为什么HttpURLConnection不发送数据,除非我尝试接收某些内容,java,http,httpurlconnection,Java,Http,Httpurlconnection,我无法理解为什么下面的代码没有将数据包放到wire上(通过wireshark确认)。我相信,这是发送HTTPPOST请求的一种相当标准的方法。我不打算读任何东西,只要POST private void sendRequest() throws IOException { String params = "param=value"; URL url = new URL(otherUrl.toString()); HttpURLConnection con = (HttpUR

我无法理解为什么下面的代码没有将数据包放到wire上(通过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
被发送,然后
200ok
被发回。顺序是正确的。也就是说,在发送邮件之前,我没有收到一些疯狂的回复。其他一切看起来都完全一样(如果需要,我可以附上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的服务器和端口都是相同的,所以我相信可以使用相同的套接字进行通信。上面的代码可以正常工作并检索数据


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

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


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

即使用户手动指定内容长度标题(如本例中所示),这也是真的吗?是的。手动设置它没有效果。Java总是设置它,除非在我提到的不需要它的情况下。我不认为查看它的值有什么区别。文件完成后会出现
200 OK
消息。
con.setDoInput(false)的目的是什么然后。由于缓冲,我显然不能在这种情况下使用它。这完全违反直觉。我不认为我的方法是错误的,但是我的代码不起作用。我知道它会被缓冲,当然我们应该关心响应代码。但是有一个选项,
setDoInput(false)
。对我来说,它要么没有意义(应该被禁止),要么不起作用。我已经描述了它是如何工作的。由你来消化这些信息。注意:唯一能知道是否有200响应的方法是查看其值。你的代码不能做到这一点。