在Java中,如何撰写HTTP请求消息并将其发送到HTTP web服务器?


当前回答

如果您正在使用Java 11或更新版本(Android除外),而不是遗留的HttpUrlConnection类,您可以使用Java 11新的HTTP客户端API。

一个示例GET请求:

var uri = URI.create("https://httpbin.org/get?age=26&isHappy=true");
var client = HttpClient.newHttpClient();
var request = HttpRequest
        .newBuilder()
        .uri(uri)
        .header("accept", "application/json")
        .GET()
        .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());

同一请求异步执行:

var responseAsync = client
        .sendAsync(request, HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(System.out::println);
// responseAsync.join(); // Wait for completion

一个POST请求的例子:

var request = HttpRequest
        .newBuilder()
        .uri(uri)
        .version(HttpClient.Version.HTTP_2)
        .timeout(Duration.ofMinutes(1))
        .header("Content-Type", "application/json")
        .header("Authorization", "Bearer fake")
        .POST(BodyPublishers.ofString("{ title: 'This is cool' }"))
        .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());

要以多部分(multipart/form-data)或url编码(application/x-www-form-urlencoded)格式发送表单数据,请参阅此解决方案。

有关HTTP客户端API的示例和更多信息,请参阅本文。

对于Java标准库HTTP服务器,请参阅这篇文章。

其他回答

Apache HttpComponents。这两个模块的例子——HttpCore和HttpClient会让你马上开始。

并不是说HttpUrlConnection是一个糟糕的选择,HttpComponents将抽象出大量繁琐的编码。如果你真的想用最少的代码来支持大量的HTTP服务器/客户端,我推荐这样做。顺便说一下,HttpCore可以用于功能最少的应用程序(客户端或服务器),而HttpClient用于需要支持多种身份验证方案、cookie支持等的客户端。

我知道其他人会推荐Apache的http-客户端,但是它增加了复杂性(例如,更多可能出错的东西),这是很少被保证的。对于简单的任务,可以使用java.net.URL。

URL url = new URL("http://www.y.com/url");
InputStream is = url.openStream();
try {
  /* Now read the retrieved document from the stream. */
  ...
} finally {
  is.close();
}

来自Oracle的java教程

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

public class URLConnectionReader {
    public static void main(String[] args) throws Exception {
        URL yahoo = new URL("http://www.yahoo.com/");
        URLConnection yc = yahoo.openConnection();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                yc.getInputStream()));
        String inputLine;

        while ((inputLine = in.readLine()) != null) 
            System.out.println(inputLine);
        in.close();
    }
}

这里有一个通过Example Depot发送POST请求的链接::

try {
    // Construct data
    String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
    data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8");

    // Send data
    URL url = new URL("http://hostname:80/cgi");
    URLConnection conn = url.openConnection();
    conn.setDoOutput(true);
    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
    wr.write(data);
    wr.flush();

    // Get the response
    BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String line;
    while ((line = rd.readLine()) != null) {
        // Process line...
    }
    wr.close();
    rd.close();
} catch (Exception e) {
}

如果您想发送一个GET请求,您可以稍微修改代码以满足您的需要。具体来说,您必须在URL的构造函数中添加参数。然后,还注释掉这个wr.write(data);

有一件事没有写下来,你应该注意,就是超时。特别是如果你想在WebServices中使用它,你必须设置超时,否则上面的代码将无限期地等待,或者至少等待很长时间,这可能是你不想要的。

超时设置如下conn.setReadTimeout(2000);输入参数以毫秒为单位

下面是一个完整的Java 7程序:

class GETHTTPResource {
  public static void main(String[] args) throws Exception {
    try (java.util.Scanner s = new java.util.Scanner(new java.net.URL("http://example.com/").openStream())) {
      System.out.println(s.useDelimiter("\\A").next());
    }
  }
}

新的try-with-resources将自动关闭Scanner,而Scanner将自动关闭InputStream。