这里经常会问到java.net.URLConnection的使用,Oracle教程对此过于简洁。

该教程基本上只展示了如何发出GET请求并读取响应。它没有解释如何使用它来执行POST请求、设置请求头、读取响应头、处理cookie、提交HTML表单、上传文件等。

那么,我如何使用java.net.URLConnection来激发和处理“高级”HTTP请求?


当前回答

您还可以使用jcabi http(我是一名开发人员)的JdkRequest,它为您完成所有这些工作,装饰HttpURLConnection、激发http请求和解析响应,例如:

String html = new JdkRequest("http://www.google.com").fetch().body();

查看此日志以了解更多信息:http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

其他回答

如果您使用的是HTTP GET,请删除此行:

urlConnection.setDoOutput(true);

在使用HTTP时,引用HttpURLConnection而不是基类URLConnection几乎总是更有用(因为URLConnection是一个抽象类,当您在HTTP URL上请求URLConnection.openConnection()时,无论如何都会返回)。

然后,您可以不依赖URLConnection#setDoOutput(true)将请求方法隐式设置为POST,而是使用httpURLConnection.setRequestMethod(“POST”),有些人可能会觉得这更自然(这也允许您指定其他请求方法,如PUT、DELETE…)。

它还提供了有用的HTTP常量,因此您可以执行以下操作:

int responseCode = httpURLConnection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

HTTP URL命中有两个选项:GET/POST

GET请求:

HttpURLConnection.setFollowRedirects(true); // Defaults to true

String url = "https://name_of_the_url";
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
System.out.println(String.valueOf(http_conn.getResponseCode()));

POST请求:

HttpURLConnection.setFollowRedirects(true); // Defaults to true

String url = "https://name_of_the_url"
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
http_conn.setDoOutput(true);
PrintWriter out = new PrintWriter(http_conn.getOutputStream());
if (urlparameter != null) {
   out.println(urlparameter);
}
out.close();
out = null;
System.out.println(String.valueOf(http_conn.getResponseCode()));

最初,我被这篇有利于HttpClient的文章误导了。

后来,我意识到HttpURLConnection将继续留在本文中。

根据谷歌博客:

Apache HTTP客户端在Eclair和Froyo上的bug更少。这是这些版本的最佳选择。对于姜饼,HttpURLConnection是最佳选择。其简单的API和小巧的尺寸使其非常适合Android。透明压缩和响应缓存减少了网络使用,提高了速度并节省了电池。新应用程序应使用HttpURLConnection;这是我们今后将花费精力的地方。

在阅读了这篇文章和一些其他堆栈流问题之后,我确信HttpURLConnection将持续更长的时间。

支持HttpURLConnection的一些SE问题:

在Android上,使用URL编码表单数据进行POST请求,而不使用UrlEncodedFormEntity

HttpPost适用于Java项目,但不适用于Android

如果您使用的是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服务器,请参阅本文。