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 的原子整数计数器

逐层拆解:

  1. AtomicInteger

    • Java 提供的线程安全整数类
    • 专为多线程环境设计,保证操作的原子性(操作不可被中断)
  2. new AtomicInteger(1)

    • 实例化一个原子整数对象
    • 括号中的 1 表示初始值(计数器从 1 开始)

** 关键特性(为什么不用普通 int?)**

普通 int AtomicInteger
❌ 非线程安全 线程安全
i++ 在多线程中会出错 getAndIncrement() 是原子操作
❌ 无并发控制机制 ✅ 基于 CAS 实现无锁并发
  • count.getAndIncrement() 等价于:
    1. 读取当前值(如 1
    2. 自动执行 值+1(变成 2
    3. 返回原始值(返回 1
  • 每次请求时:
    第1次请求 → 添加 Header: "Count:1" → 值变成2
    第2次请求 → 添加 Header: "Count:2" → 值变成3
    ...依此类推

示例中实现「跨请求连续计数」的关键:即使 HTTP 客户端在多线程环境下处理请求,也能保证每个请求获得唯一递增的编号


知识点提炼

1. 核心功能

  • 处理特定HTTP头部
  • 操作消息内容实体(如压缩/解压缩)
  • 通过装饰器模式包装原始实体

2. 协作机制

  • 使用HTTP上下文(HttpContext) 跨请求共享数据(如计数器)

3. 执行顺序

  • 默认执行顺序无关,存在依赖时需显式指定添加顺序

4. 线程安全

  • 禁止使用非同步的实例变量(类似Servlet规范)

5. 状态持久化

  • 上下文可保存跨请求的状态(示例中的计数器)

关键理解:拦截器像可插拔的功能模块,通过共享的"记事本"协作,高效安全地处理HTTP消息的各个环节。

posted @ 2025-07-24 09:44  hqq的进阶日记  阅读(11)  评论(0)    收藏  举报