一,HttpURLConnection介绍
HttpURLConnection一个抽象类是标准的JAVA接口,该类位于java.net包中,它提供了基本的URL请求,响应等功能。
HttpURLConnection是基于http协议的,支持GET、POST、PUT、DELETE等各种请求方式。如果使用HTTPS协议请求,可以使用它的子类HttpsURLConnection完成更安全的请求操作。
二,使用步骤
-
创建连接
URL url = new URL("https://example.com/api"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); -
设置请求方法
conn.setRequestMethod("GET"); // 支持 GET、POST、PUT、DELETE 等 -
添加请求头
conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("User-Agent", "MyApp/1.0"); -
处理请求参数
-
GET 请求参数:直接附加到 URL 后,如
?key1=value1&key2=value2。 -
POST 请求参数:通过输出流发送:
conn.setDoOutput(true); // 允许写入请求体 try (OutputStream os = conn.getOutputStream()) { String data = "key1=value1&key2=value2"; os.write(data.getBytes(StandardCharsets.UTF_8)); }
-
-
处理响应
int statusCode = conn.getResponseCode(); // 200、404、500 等 if (statusCode == HttpURLConnection.HTTP_OK) { try (BufferedReader reader = new BufferedReader( new InputStreamReader(conn.getInputStream()))) { String line; StringBuilder response = new StringBuilder(); while ((line = reader.readLine()) != null) { response.append(line); } System.out.println("Response: " + response.toString()); } } else { // 处理错误流(如 4xx/5xx) try (BufferedReader errorReader = new BufferedReader( new InputStreamReader(conn.getErrorStream()))) { // 读取错误信息... } } -
释放资源
conn.disconnect(); // 释放资源(但 Java 通常会自动处理)
-
超时设置
conn.setConnectTimeout(5000); // 连接超时(毫秒) conn.setReadTimeout(10000); // 读取超时(毫秒)
三,HttpURLConnection方法详解
3.1 设置连接参数方法
| 方法 | 说明 |
|---|---|
setAllowUserInteraction(boolean allowuserinteraction) | 如果为 true,则在允许用户交互(例如弹出一个身份验证对话框)的上下文中对此 URL 进行检查,默认false |
setDoInput (boolean doinput) | 用于设置是否从HTTP连接读取数据。默认情况下,这个值是 true,表示连接会用于输入操作。 |
setDoOutput(boolean dooutput) | 用于设置是否使用此连接进行输出操作。通常用于需要向服务器发送数据的请求,比如POST请求,如果设置为 true,表示将使用此连接进行输出操作;如果设置为 false,表示不进行输出操作,默认false |
setIfModifiedSince(long ifmodifiedsince) | 用于设置If-Modified-Since请求头,该请求头是HTTP协议中的一种条件请求头。它告诉服务器只有在指定的时间之后资源被修改时,才返回资源。如果资源自指定时间以来没有被修改,服务器将返回304 Not Modified响应,并且不返回资源内容。 |
setUseCaches(boolean useCaches) | 用于设置是否允许使用缓存。如果设置为 true,则允许从缓存中获取资源;如果设置为 false,则不使用缓存,每次都从服务器获取资源。默认为true |
setDefaultAllowUserInteraction(boolean defaultallowuserinteraction) | 用于设置所有后续的连接对象是否允许用户交互。它设置的是一个全局默认值,影响所有通过HttpURLConnection类创建的新连接,如果设置为 true,表示允许用户交互;如果设置为 false,表示不允许用户交互。默认false |
setDefaultUseCaches(boolean defaultusecaches) | 用于设置所有后续创建的HttpURLConnection实例的缓存使用策略。它设置的是一个全局默认值,影响所有通过HttpURLConnection类创建的新连接,如果设置为 true,表示允许使用缓存;如果设置为 false,表示不使用缓存。 |
3.2 设置请求头
| 方法 | 说明 |
|---|---|
setRequestProperty(key,value) | 设置一般请求属性。如果已存在具有该关键字的属性,则覆盖。注:HTTP 要求所有能够合法拥有多个具有相同键的实例的请求属性,使用以逗号分隔的列表语法,这样可实现将多个属性添加到一个属性中。 |
addRequestProperty(key,value) | 添加由键值对指定的一般请求属性。此方法不会改写与相同键关联的现有值 |
3.3 传递参数给服务器
| 方法 | 说明 |
|---|---|
public OutputStream getOutputStream() throws IOException | 用于获取连接的输出流,允许将数据发送到服务器。这个方法通常用于需要将数据发送到服务器的请求,比如 HTTP POST 或 PUT 请求。 |
3.4 获取响应内容
| 方法 | 说明 |
|---|---|
public Object getContent() throws IOException | 用于获取HTTP响应的内容。该方法的返回值是一个Object,通常是一个流对象,如InputStream或Reader,根据具体的内容类型而定。这个方法提供了一个简便的方式来获取响应体,而不需要直接处理底层的流操作。 |
public String getHeaderField(String name) | 用于获取响应头中指定字段的值。你可以通过该方法来检索HTTP响应头中某个字段的值,如 Content-Type、Content-Length 等。 |
public InputStream getInputStream() throws IOException | 用于获取连接的输入流,以便读取从服务器返回的响应数据。这个方法适用于处理响应体内容,例如读取网页内容、API 返回的数据等。getInputStream 方法会抛出 IOException 异常,如果服务器响应状态码不是成功状态码(如404或500),则可能需要调用 getErrorStream 来读取错误信息。 |
public int getResponseCode() throws IOException | 用于获取服务器响应的HTTP状态码。HTTP状态码是服务器对客户端请求的响应代码,指示请求的结果或状态。 |
public String getResponseMessage() throws IOException | 用于获取与HTTP响应状态码相关的描述性消息。这个方法返回的消息是对状态码的简短描述,比如 "OK"、"Not Found" 或 "Internal Server Error"。 |
3.5 获取响应头
| 方法 | 说明 |
|---|---|
public String getContentEncoding() | 用于获取响应体的内容编码类型。如果该字段在响应头中存在,它会返回编码类型的字符串。 |
public int getContentLength() | 用于获取HTTP响应体的内容长度。该方法返回的长度以字节为单位,通常用于确定响应体的大小,帮助处理和管理响应数据。 |
public String getContentType() | 用于获取HTTP响应头中的 Content-Type 字段。这个字段表示响应体的媒体类型(MIME类型),用于描述响应内容的类型,例如 text/html、application/json、image/png 等。 |
public long getDate() | 用于获取HTTP响应头中的 Date 字段。这个字段表示响应被发送的日期和时间。返回的日期和时间是标准的 HTTP 日期格式,通常用于记录和处理服务器响应的时间信息。 |
public long getExpiration() | 用于获取HTTP响应头中 Expires 字段的时间戳值,以毫秒为单位,表示响应的过期时间。这个方法提供了一种简便的方式来获取响应的过期时间,而无需手动解析日期字符串。 |
四,代码示例
4.1 GET 请求示例
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class GetExample {
public static void main(String[] args) throws Exception {
String url = "https://jsonplaceholder.typicode.com/posts/1";
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
// 设置请求方法
conn.setRequestMethod("GET");
// 添加请求头(可选)
conn.setRequestProperty("User-Agent", "Java Client");
//处理响应
int responseCode = conn.getResponseCode();
System.out.println("GET Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
try (BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
System.out.println("Response Body: " + response);
}
} else {
System.out.println("GET Request Failed");
}
conn.disconnect();
}
}
4.2 POST 请求示例
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class PostExample {
public static void main(String[] args) throws Exception {
String url = "https://jsonplaceholder.typicode.com/posts";
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
// 设置请求方法
conn.setRequestMethod("POST");
// 添加请求头(JSON 格式)
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
// 允许写入请求体
conn.setDoOutput(true);
// 构造请求体
String jsonBody = "{\"title\":\"foo\",\"body\":\"bar\",\"userId\":1}";
byte[] postData = jsonBody.getBytes(StandardCharsets.UTF_8);
// 发送请求体
try (OutputStream os = conn.getOutputStream()) {
os.write(postData);
os.flush();
}
//处理响应
int responseCode = conn.getResponseCode();
System.out.println("POST Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_CREATED) { // 201 表示创建成功
try (BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
System.out.println("Response Body: " + response);
}
} else {
System.out.println("POST Request Failed");
}
conn.disconnect();
}
}
4.3 PUT 请求示例
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class PutExample {
public static void main(String[] args) throws Exception {
String url = "https://jsonplaceholder.typicode.com/posts/1";
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
// 设置请求方法
conn.setRequestMethod("PUT");
// 添加请求头
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
// 构造请求体
String jsonBody = "{\"id\":1,\"title\":\"updated title\",\"body\":\"updated body\"}";
byte[] putData = jsonBody.getBytes(StandardCharsets.UTF_8);
// 发送请求体
try (OutputStream os = conn.getOutputStream()) {
os.write(putData);
os.flush();
}
int responseCode = conn.getResponseCode();
System.out.println("PUT Response Code: " + responseCode);
//处理响应
if (responseCode == HttpURLConnection.HTTP_OK) { // 200 表示成功
try (BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
System.out.println("Response Body: " + response);
}
} else {
System.out.println("PUT Request Failed");
}
conn.disconnect();
}
}
4.4 DELETE 请求示例
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class DeleteExample {
public static void main(String[] args) throws Exception {
String url = "https://jsonplaceholder.typicode.com/posts/1";
URL obj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
// 设置请求方法
conn.setRequestMethod("DELETE");
//处理响应
int responseCode = conn.getResponseCode();
System.out.println("DELETE Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // 200 表示成功
try (BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
System.out.println("Response Body: " + response);
}
} else {
System.out.println("DELETE Request Failed");
}
conn.disconnect();
}
}
4.5 关键说明
- 请求方法设置:通过
setRequestMethod()指定GET/POST/PUT/DELETE。 - 请求体处理:
- POST/PUT:必须设置
setDoOutput(true),并通过getOutputStream()写入数据。 - GET/DELETE:通常无需请求体(但 DELETE 可以有请求体,具体取决于 API 设计)。
- POST/PUT:必须设置
- 响应处理:
- 使用
getInputStream()读取成功响应(如 200/201)。 - 使用
getErrorStream()读取错误响应(如 4xx/5xx)。
- 使用
- 资源释放:通过
conn.disconnect()主动关闭连接(尽管 Java 会自动处理,但显式调用更安全)。
4.6 注意事项
- 异常处理:实际代码中需用
try-catch处理IOException。 - 字符编码:始终明确指定字符编码(如
StandardCharsets.UTF_8)。 - HTTPS 支持:默认支持 HTTPS,但自签名证书需额外配置
SSLContext。 - 性能优化:频繁请求时建议复用连接或使用更高级库(如 OkHttp)。