使用HttpURLConnection在Java中发布

使用HttpURLConnection在Java中发布,java,http,Java,Http,我读过很多关于使用HttpURLConnection的HTTP帖子,也尝试过很多,我遇到的几乎所有东西都有类似的结构,从以下三行开始: url = new URL(targetURL); connection = (HttpURLConnection)url.openConnection(); connection.setRequestMethod("POST"); 当我尝试此操作时,调用setRequestMethod时,我总是会得到一个“连接已建立”异常,这非常有意义,因为我在

我读过很多关于使用HttpURLConnection的HTTP帖子,也尝试过很多,我遇到的几乎所有东西都有类似的结构,从以下三行开始:

  url = new URL(targetURL);
  connection = (HttpURLConnection)url.openConnection();
  connection.setRequestMethod("POST");
当我尝试此操作时,调用setRequestMethod时,我总是会得到一个“连接已建立”异常,这非常有意义,因为我在设置请求类型之前显然调用了openConnection。虽然阅读文档openConnection在理论上并不能打开连接

关于这个问题的帖子有很多,比如和。然而,我不明白为什么关于如何编写这段代码的每一条建议都有这样的3行

我猜这段代码在大多数情况下都能工作,因为一定有人测试过它,所以为什么这段代码对我不起作用呢?我应该如何编写此代码

我知道我还可以在那里使用其他库,我只是想知道为什么这不起作用。

根据,您需要调用
连接。setDoOutput(true)
,它才能期待
POST
请求

这使您的代码如下所示:

  url = new URL(targetURL);
  connection = (HttpURLConnection)url.openConnection();
  connection.setDoOutput(true);

我无法回答为什么问题中的可疑代码在互联网上被复制。我也无法回答为什么它似乎对某些人有效而对其他人无效。不过,我现在可以回答另一个问题了,主要是因为Luiggi向我指出了这个问题

这里的关键是理解HttpURLConnection类的复杂性。第一次创建时,该类默认为“GET”请求方法,因此在这个实例中不需要更改任何内容。以下内容相当不直观,但要将请求方法设置为“POST”,不应调用setRequestMethod(“POST”),而应调用setDoOutput(true),后者隐式地将请求方法设置为POST。一旦你做到了,你就可以走了

我相信,下面是post方法应该是什么样子。这是为了发布json,但显然可以针对任何其他内容类型进行更改

public static String doPostSync(final String urlToRead, final String content) throws IOException {
    final String charset = "UTF-8";
    // Create the connection
    HttpURLConnection connection = (HttpURLConnection) new URL(urlToRead).openConnection();
    // setDoOutput(true) implicitly set's the request type to POST
    connection.setDoOutput(true);
    connection.setRequestProperty("Accept-Charset", charset);
    connection.setRequestProperty("Content-type", "application/json");

    // Write to the connection
    OutputStream output = connection.getOutputStream();
    output.write(content.getBytes(charset));
    output.close();

    // Check the error stream first, if this is null then there have been no issues with the request
    InputStream inputStream = connection.getErrorStream();
    if (inputStream == null)
        inputStream = connection.getInputStream();

    // Read everything from our stream
    BufferedReader responseReader = new BufferedReader(new InputStreamReader(inputStream, charset));

    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = responseReader.readLine()) != null) {
        response.append(inputLine);
    }
    responseReader.close();

    return response.toString();
}

@废可乐,我读过。问题是为什么这段代码对我不起作用,我应该如何编写这段代码?如何在不调用openConnection的情况下创建连接?如果这是错误的,为什么每个人都这么建议呢?@scrasedcola我读过文件。如何在不调用openConnection的情况下创建连接?@ScrapsedCola还有一点是,文档中指出:“应该注意,URLConnection实例在创建时不会建立实际的网络连接。只有在调用URLConnection.connect()时才会发生这种情况。”所以openConnection实际上并没有连接,这三行没有其他的顺序。这就是为什么它们总是按这个顺序出现。只要请求尚未发送,就没有理由在建立连接后不能设置请求方法。我有各种各样的工作代码来实现这一点。这是你的真实代码吗?@scrasedcola“第一篇帖子”,或者说是公认的答案,都是胡说八道。在创建
HttpURLConnection
之前,您不可能调用
HttpURLConnection.setRequestMethod()
。我仍然会遇到同样的异常,首先调用setDoOutput(true)。@LuiggiMendoza感谢您提供的有趣链接。这表明调用setDoOutput(true)隐式地将请求类型设置为POST,因此不需要调用setRequestMethod。我不明白为什么同样的错误代码可以在这么多地方重复。
setDoOutput(true)
意味着
setRequestMethod(“POST”)
。没必要叫他们两个。@EJP就我所知,这并没有什么不对的。这是包含错误代码的问题。