Apache HttpClient总览

作者 : admin 本文共4759个字,预计阅读时间需要12分钟 发布时间: 2024-06-17 共1人阅读

Apache HttpClient总览插图

一、重大版本

Apache HttpClient 4.x 系列

    •    HttpClient 4.0(发布于2008年左右):这是一个重要的里程碑,标志着HttpClient从Jakarta Commons项目转移到Apache HttpComponents项目。4.0版进行了大量的重构,引入了新的连接管理模型(基于HttpCore),支持了HTTP/1.1的持久连接、连接池以及更灵活的配置选项。
    •    HttpClient 4.2(发布于2013年之前):此版本增加了对HTTP状态线支持、改进了多部分实体的处理、增强了请求参数编码,以及更强大的HTTP响应处理能力。它还引入了对国际域名(IDN)的支持,并改进了与SSL/TLS相关的功能。
    •    HttpClient 4.5(约2015年至2016年间):这个版本重点在于提升性能、增强安全性、简化API使用,并且开始为HTTP/2做准备。它包括对TLSv1.2的支持、改进的连接管理、更严格的SSL握手策略,以及对HTTP/2的初步实验性支持。

Apache HttpClient 5.x 系列

    •    HttpClient 5.0(2018年以后):这是一个重大的更新,引入了全新的HTTP/2实现,完全基于Java NIO,提供了原生的异步支持。此外,它还增强了对HTTP/1.1的性能和兼容性,改进了连接重用策略,支持了WebSocket,以及提供了更强大的请求和响应拦截器系统。
    •    后续版本:随着时间的推移,HttpClient 5.x系列通过后续的小版本更新,继续优化HTTP/2支持、修复漏洞、提升性能和稳定性,并引入更多现代Web特性支持,如HTTP/3的实验性支持、对新TLS版本的兼容性增强等。

二、代码模块

httpclient

httpcore

httpcore-nio

httpasyncclient

    1.    HttpCore:
    •    核心包:这是HttpClient库的基础,提供了HTTP协议的核心抽象和实现。它定义了HTTP请求、响应、头信息、实体内容、连接管理等基本组件。HttpCore分为两个模块:httpcore 用于NIO(非阻塞I/O)支持,而 httpcore-nio 专注于阻塞I/O模型。它是构建高性能HTTP客户端和服务端的基础。
    2.    HttpClient:
    •    高级API:基于HttpCore,HttpClient提供了更高层次的API,使得发送HTTP请求变得简单直接。它封装了复杂的HTTP协议细节,让你可以专注于业务逻辑。HttpClient支持HTTPS、认证、连接管理、重定向处理、请求和响应实体的处理等特性。
    3.    HttpAsyncClient:
    •    异步API:针对需要高性能和高并发的应用场景,HttpAsyncClient提供了异步请求处理能力。这意味着你可以在发送HTTP请求后立即返回,不阻塞当前线程,当响应到达时通过回调或Future/Promise模式处理结果。这非常适合那些需要处理大量并发请求的场景。
    4.    Connection Management:
    •    连接池管理:HttpClient支持通过ConnectionManager(如PoolingHttpClientConnectionManager)来复用连接,减少每次请求时建立和销毁TCP连接的开销。连接池管理包括连接的最大数量、超时设置、空闲连接的清理等,对于性能优化至关重要。
    5.    Request and Response Handling:
    •    请求与响应处理:HttpClient提供了丰富的API来构建HTTP请求(如GET、POST、PUT等)、设置请求头、处理请求体、解析响应等。它还支持多种实体处理器(EntityHandler)来处理不同类型的内容,如字符串、文件、流等。
    6.    Authentication and Authorization:
    •    认证与授权:支持多种认证机制,包括Basic、Digest、NTLM、Kerberos以及OAuth等,以满足不同安全需求。
    7.    Redirects and Retries:
    •    重定向与重试:自动处理HTTP重定向,并且可以配置重试策略来处理暂时性的网络问题或服务器错误。
    8.    SSL/TLS Support:
    •    SSL/TLS支持:HttpClient能够处理HTTPS请求,并允许自定义SSL上下文以支持信任管理、证书验证等安全配置。
    9.    Interceptors and Filters:
    •    拦截器与过滤器:允许插入自定义逻辑到请求/响应处理流程中,例如日志记录、请求/响应修改、计时、性能监控等。
    10.    Content Compression:
    •    内容压缩:支持请求和响应内容的自动压缩,减少网络传输的数据量,提升效率。

 三、设计哲学

CloseableHttpClient 上层使用入口,通过HttpClients工具生产

HttpClientConnectionManager 连接管理,最大连接数,单路由最大连接数

RequestConfig 请求配置,连接超时时间,读取超时时间

在Spring框架中,Spring为RestTemplate设计了兼容类,org.springframework.http.client.HttpComponentsClientHttpRequestFactory

用来直接接收HttpClient。这样就完美结合了RestTemplate和Apache HttpClient

import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

public class HttpClientPoolUtil {

    private static final int MAX_TOTAL_CONNECTIONS = 100;
    private static final int DEFAULT_MAX_PER_ROUTE = 20;
    private static final int CONNECT_TIMEOUT = 5000; // 连接超时时间,单位毫秒
    private static final int SOCKET_TIMEOUT = 10000; // 数据读取超时时间,单位毫秒

    private static volatile CloseableHttpClient httpClient;
    private static PoolingHttpClientConnectionManager connectionManager;

    private HttpClientPoolUtil() {
        // 防止外部实例化
    }

    private static synchronized void init() {
        if (httpClient != null) {
            return;
        }
        
        connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);
        
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .build();

        httpClient = HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setDefaultRequestConfig(config)
                .build();
    }

    public static String sendGetRequest(String url) throws Exception {
        if (httpClient == null) {
            init();
        }

        HttpGet httpGet = new HttpGet(url);
        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity);
            } else {
                throw new RuntimeException("Response entity is null");
            }
        }
    }

    // 可以根据需要添加其他HTTP方法如POST、PUT等
}

public class Main {
    public static void main(String[] args) {
        try {
            String response = HttpClientPoolUtil.sendGetRequest("http://example.com/api/data");
            System.out.println(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四、理解

Apache HttpClient 是一个实现了HTTP协议的客户端库,它允许Java应用程序发送HTTP请求并与Web服务器交互。从HTTP协议的角度来说,HttpClient确实是在实现一个无状态的协议。HTTP本身被设计为无状态协议,这意味着每个请求都是独立的,服务器不保留关于客户端请求之间的任何上下文信息,除非显式地通过例如Cookies等方式在请求之间传递状态。

HttpClient作为一个工具类库,它本身也是无状态的,即HttpClient实例不会在内部存储关于之前请求的信息,除非你特别配置它去保存某些状态信息(比如使用CookieStore来管理Cookies)。每次你使用HttpClient创建并发送一个新的请求时,都需要为该请求提供完整的必要信息,包括URL、请求方法、头信息、请求体等。HttpClient不会自动记住或应用前一次请求的任何配置或结果到下一次请求,除非你进行了相应的编程设计来复用这些信息。

然而,HttpClient提供了连接管理(通过PoolingHttpClientConnectionManager等)来复用物理连接,这可以提高效率,但这并不改变其无状态的本质——连接的复用是一种资源管理策略,而不是对请求间状态的维护。因此,从这个角度看,说HttpClient是一个实现无状态协议(HTTP)的无状态工具类是准确的。

本站无任何商业行为
个人在线分享 » Apache HttpClient总览
E-->