Apache HttpClient 4.5.x 学习总结七:HTTP protocol interceptors(HTTP协议拦截器)
通俗解释
想象HTTP拦截器是快递分拣流水线上的工人:
1. 各司其职
- 工人A专贴"易碎品"标签(处理头部)
- 工人B专做防震包装(内容压缩)
- 工人C专做礼品盒(装饰器模式包装)
2. 协作方式
- 工人们通过共享记事本(HTTP上下文) 传递信息
- 例如记录当前包裹是今天第100件(跨请求计数器)
3. 工作规则
- 工人顺序无关,除非有依赖(如先包装再贴标签)
- 所有工具必须公用且线程安全(避免多人争抢资源)
4. 实际场景
// 给每件包裹自动编号的工人
.addInterceptorLast((包裹, 记事本) -> {
计数器 = 记事本.get("计数");
包裹贴标签("编号:" + 计数器++);
})
通过记事本实现连续10个包裹自动编号(1,2,3...10)
翻译
HTTP协议拦截器是用于实现HTTP协议特定功能的程序。它通常针对请求/响应消息中的特定头部或相关头部进行操作,也可操作消息内容实体(如透明压缩/解压缩)。拦截器通过装饰器模式包装原始实体,多个拦截器可组合成逻辑单元。
拦截器通过HTTP执行上下文(HTTP context) 共享信息(如处理状态)。其执行顺序通常无关紧要,但存在依赖时需按顺序添加到协议处理器。拦截器必须实现为线程安全,避免使用非同步的实例变量。
示例:通过上下文在连续请求间传递计数状态:
// 创建带计数拦截器的HTTP客户端
CloseableHttpClient httpclient = HttpClients.custom()
.addInterceptorLast((request, context) -> {
AtomicInteger count = (AtomicInteger) context.getAttribute("count");
request.addHeader("Count", Integer.toString(count.getAndIncrement()));
}).build();
// 设置上下文初始值
AtomicInteger count = new AtomicInteger(1);// 初始化计数器为1
HttpClientContext localContext = HttpClientContext.create();
localContext.setAttribute("count", count);//存入上下文
// 连续执行10次请求
for (int i = 0; i < 10; i++) {
CloseableHttpResponse response = httpclient.execute(new HttpGet("http://localhost/"), localContext);
// 处理响应...
}
AtomicInteger count = new AtomicInteger(1);是 Java 中的一段代码,其核心含义是:创建一个初始值为 1 的原子整数计数器
逐层拆解:
-
AtomicInteger- Java 提供的线程安全整数类
- 专为多线程环境设计,保证操作的原子性(操作不可被中断)
-
new AtomicInteger(1)- 实例化一个原子整数对象
- 括号中的
1表示初始值(计数器从 1 开始)
** 关键特性(为什么不用普通 int?)**
普通 int |
AtomicInteger |
|---|---|
| ❌ 非线程安全 | ✅ 线程安全 |
❌ i++ 在多线程中会出错 |
✅ getAndIncrement() 是原子操作 |
| ❌ 无并发控制机制 | ✅ 基于 CAS 实现无锁并发 |
count.getAndIncrement()等价于:- 读取当前值(如
1) - 自动执行
值+1(变成2) - 返回原始值(返回
1)
- 读取当前值(如
- 每次请求时:
第1次请求 → 添加 Header: "Count:1" → 值变成2
第2次请求 → 添加 Header: "Count:2" → 值变成3
...依此类推
示例中实现「跨请求连续计数」的关键:即使 HTTP 客户端在多线程环境下处理请求,也能保证每个请求获得唯一递增的编号
知识点提炼
1. 核心功能
- 处理特定HTTP头部
- 操作消息内容实体(如压缩/解压缩)
- 通过装饰器模式包装原始实体
2. 协作机制
- 使用HTTP上下文(HttpContext) 跨请求共享数据(如计数器)
3. 执行顺序
- 默认执行顺序无关,存在依赖时需显式指定添加顺序
4. 线程安全
- 禁止使用非同步的实例变量(类似Servlet规范)
5. 状态持久化
- 上下文可保存跨请求的状态(示例中的计数器)
关键理解:拦截器像可插拔的功能模块,通过共享的"记事本"协作,高效安全地处理HTTP消息的各个环节。
浙公网安备 33010602011771号