HttpURLConnection使用及优化

发布于:2025-07-02 ⋅ 阅读:(14) ⋅ 点赞:(0)

简介

HttpURLConnection是Java标准库中的抽象子类,专门用于处理HTTP协议通信。通过URL对象的方法可获取其实例,支持配置请求方法、超时设置、请求头管理及响应处理。该抽象类提供对GET、POST等HTTP方法的实现,涵盖表单提交、输入输出流操作及状态码判断等核心功能,广泛应用于Java应用程序的网络通信模块。

使用示例

GET请求

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

public class HttpExample {
    public static void main(String[] args) throws IOException {
        // 创建URL对象
        URL url = new URL("https://api.example.com/data");
        
        // 打开连接(返回URLConnection,需强制转换为HttpURLConnection)
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        
        // 设置请求方法(默认为GET)
        connection.setRequestMethod("GET");
        
        // 配置连接参数(可选)
        connection.setConnectTimeout(5000);  // 连接超时5秒
        connection.setReadTimeout(5000);     // 读取超时5秒
        
        // 发送请求并获取响应码
        int responseCode = connection.getResponseCode();
        System.out.println("Response Code: " + responseCode);
        
        // 处理响应
        if (responseCode == HttpURLConnection.HTTP_OK) {
            // 读取响应数据
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(connection.getInputStream())
            );
            String line;
            StringBuilder response = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            System.out.println("Response: " + response.toString());
        }
        
        // 断开连接(释放资源)
        connection.disconnect();
    }
}

POST请求

import java.io.*;
import java.net.*;
import java.util.zip.GZIPInputStream;

public class HttpJsonExample {
    public static void main(String[] args) {
        try {
            // 创建URL
            URL url = new URL("https://api.example.com/users");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            
            // 配置请求
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            
            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "application/json");
            connection.setRequestProperty("Accept-Encoding", "gzip");
            
            // 写入请求体
            String requestBody = "{\"name\":\"Alice\",\"email\":\"alice@example.com\"}";
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = requestBody.getBytes("utf-8");
                os.write(input, 0, input.length);
            }
            
            // 获取响应
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);
            
            // 读取响应内容
            InputStream inputStream;
            if (responseCode >= 200 && responseCode < 300) {
                inputStream = connection.getInputStream();
            } else {
                inputStream = connection.getErrorStream();
            }
            
            // 处理压缩
            if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) {
                inputStream = new GZIPInputStream(inputStream);
            }
            
            // 读取响应文本
            try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(inputStream, "UTF-8"))) {
                
                String line;
                StringBuilder response = new StringBuilder();
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                System.out.println("Response: " + response.toString());
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

HttpURLConnection优化

在使用 HttpURLConnection 进行 HTTP 请求时,为了提高请求效率并确保无乱码,你可以采取以下几个步骤:

1. 设置合适的超时时间

连接超时 (setConnectTimeout): 设置建立连接的最长时间。

读取超时 (setReadTimeout): 设置从服务器读取数据的最长时间。

例如,设置连接超时和读取超时为5秒和10秒:

HttpURLConnection connection = (HttpURLConnection) new URL("http://example.com").openConnection();
connection.setConnectTimeout(5000); // 5秒
connection.setReadTimeout(10000); // 10秒

2. 指定字符编码

确保在发送请求和接收响应时使用正确的字符编码。对于 GET 和 POST 请求,通常在 URL 中或者在请求头中指定编码。

对于 GET 请求,URL 应该已经编码好。

对于 POST 请求,可以在请求头中设置 Content-Type 并指定字符集,例如:

connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

3. 正确处理响应编码

在读取响应时,确保使用了正确的字符编码来解析响应体。通常,响应的编码可以在响应头中找到,例如 Content-Type 中的 charset 参数。

InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
    response.append(line);
}
reader.close();

辅助方法 getCharsetFromContentType 可以从 Content-Type 头中提取字符集:

private static String getCharsetFromContentType(String contentType) {
    String charset = null;
    if (contentType != null && contentType.contains("charset=")) {
        charset = contentType.substring(contentType.indexOf("charset=") + 8);
    } else {
        charset = "UTF-8"; // 默认字符集
    }
    return charset;
}

4. 使用压缩传输(如果适用)

如果服务器支持 gzip 压缩,可以在请求头中添加 Accept-Encoding 来请求压缩的响应:

connection.setRequestProperty("Accept-Encoding", "gzip");

5. 关闭连接释放资源

确保在完成请求后关闭连接,释放网络资源。可以使用 try-with-resources 语句来自动管理资源:

try (HttpURLConnection connection = (HttpURLConnection) new URL("http://example.com").openConnection()) {
    // 设置连接和读取超时等操作
    // 获取响应等操作
} catch (IOException e) {
    e.printStackTrace();
} // try-with-resources 会自动关闭连接

6. 启用持久连接(Keep-Alive),减少握手开销

HTTP/1.1 默认启用持久连接(Keep-Alive),可复用 TCP 连接处理多次请求(避免重复三次握手),但需正确配置请求头并合理管理连接生命周期。

// 显式声明持久连接(HTTP/1.1默认支持,此配置可增强兼容性)
connection.setRequestProperty("Connection", "keep-alive");

// 复用连接:若多次请求同一服务器,可复用当前连接(无需每次调用disconnect())
// 注意:仅在多次请求且服务器支持持久连接时生效

注意:若不再使用连接,需在finally中调用connection.disconnect()释放资源;但多次请求同一服务器时,可延迟调用以复用连接。
通过上述步骤,你可以提高 HTTP 请求的效率并确保无乱码。