기술나눔

Java가 HttpClientUtils를 사용하여 HTTP 요청을 시작하는 방법

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina


I. 소개

현대 소프트웨어 개발에서는 데이터를 가져오거나 데이터를 보내는 등 원격 서버와 통신해야 하는 경우가 많습니다. Apache HttpClient는 HTTP 요청의 시작 및 응답 처리를 단순화하는 널리 사용되는 Java HTTP 클라이언트 라이브러리입니다.이 기사에서는 사용자 정의를 사용하는 방법을 소개합니다.HttpClientUtils Apache HttpClient를 사용하여 POST 요청을 시작하고 연결 풀을 관리하여 성능을 최적화하는 클래스입니다.

1.HttpClientUtils 클래스 개요

public class HttpClientUtils {
    // 静态常量和变量声明
    private static final int MAX_TOTAL_CONN = 600;
    private static final int MAX_CONN_PER_HOST = 300;
    private static final int SOCKET_TIMEOUT = 5000;
    private static final int CONNECTION_TIMEOUT = 200;
    private static final int CONNECTION_MANAGER_TIMEOUT = 100;

    private static CloseableHttpClient httpclient;
    private static PoolingHttpClientConnectionManager connMrg;
    private static String encoding = StandardCharsets.UTF_8.name();
    private static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);
    private static final ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(2);

    // 静态代码块,用于初始化 HttpClient 和连接管理器,并设置 JVM 退出时关闭 HttpClient
    static {
        init();
        destroyByJvmExit();
    }

    // 初始化连接管理器和 HttpClient
    private static void init() {
        connMrg = new PoolingHttpClientConnectionManager();
        connMrg.setMaxTotal(MAX_TOTAL_CONN);
        connMrg.setDefaultMaxPerRoute(MAX_CONN_PER_HOST);

        httpclient = HttpClients.custom()
                .setConnectionManager(connMrg)
                .setDefaultRequestConfig(HttpClientUtils.defaultRequestConfig())
                .build();

        // 定时任务,定期清理过期和空闲连接
        scheduledService.scheduleAtFixedRate(() -> {
            connMrg.closeExpiredConnections();
            connMrg.closeIdleConnections(CONNECTION_MANAGER_TIMEOUT, TimeUnit.MILLISECONDS);
        }, 0, CONNECTION_MANAGER_TIMEOUT, TimeUnit.MILLISECONDS);
    }

    // JVM 退出时关闭 HttpClient
    private static void destroyByJvmExit() {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                httpclient.close();
            } catch (IOException e) {
                log.error("Error closing HttpClient: {}", e.getMessage());
            }
        }));
    }

    // 创建 HttpClientContext
    private static HttpClientContext createContext() {
        return HttpClientContext.create();
    }

    // 创建默认的 RequestConfig
    private static RequestConfig defaultRequestConfig() {
        return RequestConfig.custom()
                .setConnectTimeout(CONNECTION_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .setConnectionRequestTimeout(CONNECTION_MANAGER_TIMEOUT)
                .build();
    }

    // 发起带参数的 POST 表单请求,返回字符串结果
    public static String postWithParamsForString(String url, List<NameValuePair> params) {
        HttpPost httpPost = new HttpPost();
        try {
            URI uri = new URIBuilder(url).build();
            httpPost.setURI(uri);
            httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));

            return executeRequest(httpPost);
        } catch (URISyntaxException | IOException e) {
            log.error("Error executing POST request: {}", e.getMessage());
        } finally {
            httpPost.releaseConnection();
        }
        return null;
    }
    
    // 发起 GET 请求,返回字符串结果
    public static String get(String url, List<NameValuePair> params) {
        HttpGet httpGet = new HttpGet();
        try {
            URI uri = new URIBuilder(url).setParameters(params).build();
            httpGet.setURI(uri);

            return executeRequest(httpGet);
        } catch (URISyntaxException | IOException e) {
            log.error("HTTP GET request failed", e);
        } finally {
            httpGet.releaseConnection();
        }
        return null;
    }

    // 发起 Post 请求,返回字符串结果
    public static String post(String url, List<NameValuePair> params) {
        HttpPost httpPost = new HttpPost();
        try {
            httpPost.setURI(new URI(url));
            httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));

            return executeRequest(httpPost);
        } catch (URISyntaxException | IOException e) {
            log.error("HTTP POST request failed", e);
        } finally {
            httpPost.releaseConnection();
        }
        return null;
    }

    // 执行 HTTP 请求并处理响应
    private static String executeRequest(HttpUriRequest request) throws IOException {
        try (CloseableHttpResponse response = httpclient.execute(request, createContext())) {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return EntityUtils.toString(entity, encoding);
                } else {
                    log.warn("Empty response entity");
                }
            } else {
                log.error("HTTP request failed with status code: {}", statusCode);
            }
        } catch (IOException e) {
            log.error("HTTP request execution failed: {}", e.getMessage());
            throw e;
        }
        return null;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133

2. HttpClientUtils 클래스 구문 분석

  1. 정적 상수 및 변수:

    • 최대 연결 수, 연결 시간 초과, 소켓 시간 초과 등과 같은 상수 및 변수를 정의합니다.
  2. 초기화 및 파기:

    • 정적 코드 블록에서 초기화됨 HttpClient 및 연결 관리자PoolingHttpClientConnectionManager
    • 사용 ScheduledExecutorService 만료된 연결과 유휴 연결을 정기적으로 정리합니다.
    • 존재하다 destroyByJvmExit 이 방법에서는 JVM이 종료될 때 JVM 종료 후크가 닫히도록 JVM 종료 후크가 등록됩니다.HttpClient
  3. HTTP 요청 방법:

    • postWithParamsForString 메소드는 매개변수를 사용하여 POST 요청을 수행하는 데 사용됩니다.
    • 사용 HttpPost 요청을 작성하고, URL 및 요청 매개변수를 설정하고, 마지막으로 호출합니다.executeRequest 메소드 실행 요청.
  4. 요청 실행 및 응답 처리:

    • executeRequest 방법 수신HttpUriRequest, HTTP 요청을 수행하고 응답을 처리합니다.
    • 응답의 상태 코드를 확인하고, 200(OK)이면 응답 엔터티를 읽어 문자열로 변환하여 반환한다.
    • 로깅을 사용하여 오류 및 경고 메시지를 기록하면 코드의 견고성과 신뢰성을 보장할 수 있습니다.

3. HttpClientUtils 클래스를 사용하세요.

사용 HttpClientUtils 클래스는 HTTP 요청의 작성 및 관리를 단순화할 수 있습니다. 구체적인 단계는 다음과 같습니다.

public class Main {
    public static void main(String[] args) {
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("param1", "value1"));
        params.add(new BasicNameValuePair("param2", "value2"));

        String response = HttpClientUtils.postWithParamsForString("http://example.com/api", params);
        if (response != null) {
            System.out.println("Response: " + response);
        } else {
            System.err.println("Failed to execute POST request");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

위의 학습을 통해 이제 사용법을 이해하게 되었습니다. HttpClientUtils HTTP 클라이언트를 관리하고 요청을 시작하는 클래스입니다. 이 접근 방식을 사용하면 Java 애플리케이션에서 HTTP 통신을 보다 효율적으로 처리하는 동시에 연결 풀링 및 주기적인 정리 메커니즘을 통해 성능과 안정성을 향상시킬 수 있습니다.