用HttpUtils这么久,是时候自己手搓一个Http 请求工具包了

948 阅读1分钟

HttpUtils 是一个 Java HTTP 请求工具包,提供了发送 GET/POST 请求的方法,并支持自动处理重定向和 Cookies。该工具包通常用于在 Java 应用程序中发送 HTTP 请求,获取响应结果。

废话不多说,直接上代码

import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;

public class HttpUtils {

    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36";
    private static final Map<String, String> cookies = new HashMap<>(); // 用于保存 Cookies

    public static String sendGet(String url) throws IOException {
        return sendGet(url, new HashMap<String, String>(), false);
    }

    public static String sendGet(String url, Map<String, String> headers, boolean followRedirects) throws IOException {
        URL requestUrl = new URL(url);
        HttpURLConnection con = (HttpURLConnection) requestUrl.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", USER_AGENT);

        for (Map.Entry<String, String> entry : headers.entrySet()) {
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }

        if (!followRedirects) {
            con.setInstanceFollowRedirects(false);
        }

        // 添加缓存控制
        con.setRequestProperty("Cache-Control", "max-age=0");
        con.setRequestProperty("Pragma", "no-cache");

        // 添加 Cookies
        StringBuilder cookieBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : cookies.entrySet()) {
            cookieBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("; ");
        }
        if (cookieBuilder.length() > 0) {
            con.setRequestProperty("Cookie", cookieBuilder.toString());
        }

        int responseCode = con.getResponseCode();

        // 处理重定向
        if (followRedirects && (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP)) {
            String newUrl = con.getHeaderField("Location");
            con.disconnect();
            return sendGet(newUrl, headers, true);
        } else if (responseCode == HttpURLConnection.HTTP_OK) {
            // 保存 Cookies
            Map<String, List<String>> responseHeaders = con.getHeaderFields();
            for (Map.Entry<String, List<String>> entry : responseHeaders.entrySet()) {
                if ("Set-Cookie".equalsIgnoreCase(entry.getKey())) {
                    List<String> values = entry.getValue();
                    cookies.put(values.get(0), values.get(1));
                }
            }
            
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();

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

            return response.toString();
        } else {
            throw new RuntimeException("GET request failed: " + responseCode);
        }
    }

    public static String sendPost(String url, String data) throws IOException {
        return sendPost(url, data, new HashMap<String, String>(), false);
    }

    public static String sendPost(String url, String data, Map<String, String> headers, boolean followRedirects) throws IOException {
        URL requestUrl = new URL(url);

        HttpURLConnection con;
        if (url.startsWith("https://")) {
            con = (HttpsURLConnection) requestUrl.openConnection();
        } else {
            con = (HttpURLConnection) requestUrl.openConnection();
        }

        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", USER_AGENT);

        for (Map.Entry<String, String> entry : headers.entrySet()) {
            con.setRequestProperty(entry.getKey(), entry.getValue());
        }

        if (!followRedirects) {
            con.setInstanceFollowRedirects(false);
        }

        // 添加缓存控制
        con.setRequestProperty("Cache-Control", "no-cache");
        con.setRequestProperty("Pragma", "no-cache");

        // 添加 Cookies
        StringBuilder cookieBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : cookies.entrySet()) {
            cookieBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("; ");
        }
        if (cookieBuilder.length() > 0) {
            con.setRequestProperty("Cookie", cookieBuilder.toString());
        }

        con.setDoOutput(true);
        OutputStream os = con.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
        osw.write(data);
        osw.flush();
        osw.close();

        int responseCode = con.getResponseCode();

        // 处理重定向
        if (followRedirects && (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP)) {
            String newUrl = con.getHeaderField("Location");
            con.disconnect();
            return sendGet(newUrl, headers, true);
        } else if (responseCode == HttpURLConnection.HTTP_OK) {
            // 保存 Cookies
            Map<String, List<String>> responseHeaders = con.getHeaderFields();
            for (Map.Entry<String, List<String>> entry : responseHeaders.entrySet()) {
                if ("Set-Cookie".equalsIgnoreCase(entry.getKey())) {
                    List<String> values = entry.getValue();
                    cookies.put(values.get(0), values.get(1));
                }
            }

            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuilder response = new StringBuilder();

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

            return response.toString();
        } else {
            throw new RuntimeException("POST request failed: " + responseCode);
        }
    }
}

使用示例:

public static void main(String[] args) throws IOException {
    // 发送 GET 请求
    String getUrl = "http://www.baidu.com";
    Map<String, String> getHeaders = new HashMap<>();
    getHeaders.put("Authorization", "Bearer xxxxxx");
    String getResponse = HttpUtils.sendGet(getUrl, getHeaders, true);
    System.out.println("GET response: " + getResponse);

    // 发送 POST 请求
    String postUrl = "http://www.example.com";
    String postData = "param1=value1&param2=value2";
    Map<String, String> postHeaders = new HashMap<>();
    postHeaders.put("Content-Type", "application/x-www-form-urlencoded");
    String postResponse = HttpUtils.sendPost(postUrl, postData, postHeaders, true);
    System.out.println("POST response: " + postResponse);
}