This is the multi-page printable view of this section.
Click here to print.
Return to the regular view of this page.
Interceptor
在HttpRequest处理过程中,有时可能需要执行Retry、Redirect、Cache等操作,使用Interceptor可以实现类似功能。
与Filter的区别
与Filter不同的是,在Interceptor中
可以同时获取HttpRequest及经过处理后的HttpResponse,甚至可以替换原始的HttpRequest及处理后的HttpResponse。更多与Filter的不同如下:
- 执行时机不同:
RequestFilter在所有拦截器对HttpRequest的处理之后才会执行,ResponseFilter在响应头接收到之后(响应body处理前)立即执行,此时所有拦截器对HttpResponse的处理均未执行。
- 关联性不同:
Interceptor中可以获取HttpRequest经过处理后的HttpResponse,通过此种方式可以将请求和响应关联起来,而RequestFilter和ResponseFilter中均无法同时获取到请求和响应,因此
也不能将两者关联起来,但是同一个请求将在RequestFilter和ResponseFilter中共享一个FilterContext实例,因此可以通过该对象传递上下文参数。
- 通过拦截器可以替换
HttpRequest或HttpResponse,而通过Filter无法实现。
鉴于Interceptor和Filter的区别,下述场景更适合使用Interceptor:
- 需要同时处理
HttpRequest及HttpResponse,如重试、重定向等(因为需要获取HttpRequest处理结果后的HttpResponse再决定下一步处理逻辑)。
HttpRequest处理过程中仅需要执行一次的逻辑,同时需要注意该类拦截器的优先级要高于重试、重定向等内置拦截器,否则发生重试、重定向时该拦类拦截器仍会被
多次执行。
- 需要替换原始的
HttpRequest或处理后的HttpResponse。
1 - 内置Interceptor
在HttpClient中存在一些内置Interceptor,用于实现 100-expect-continue、重试、重定向 等功能。
100-expect-continue
HttpClient内置了对100(“expect-continue”)响应码的支持,使用时可以设置Client或者Request级别的useExpectContinue参数为false来禁用该功能。
重试
HttpClient使用内置的RetryInterceptor实现重试功能。默认情况下,会对所有抛出连接异常的请求进行重试,其中:最大重试次数为3(不包括原始请求),重试间隔时间为0。使用时,可以通过自定义RetryOptions参数更改重试次数、重试条件、重试间隔时间等。
重定向
默认情况下,HttpClient会对响应状态码为301,302,303,307,308的请求重定向,其中:最大重定向次数为5(不包含原始请求)。使用时,可以通过maxRedirects更新重定向次数或者禁用(maxRedirects=0)重定向功能。
覆盖内置拦截器
当内置拦截器的功能不能满足用户需求时,可重写对应的内置拦截器的相关方法并通过Builder配置或者Spi加载的机制传入,此时,对应的内置拦截器将自动失效。
Note
内置拦截器默认执行顺序: 100-expect-continue > 重试 > 重定向
2 - 使用方式
HttpClient支持通过builder配置和SPI加载两种方式配置Interceptor。
Builder配置
在构造HttpClient时传入自定义的Interceptor实例,如:
final HttpClient client = HttpClient.create().addInterceptor((request, next) -> {
System.out.println("Interceptor");
return next.proceed(request);
}).build();
SPI
HttpClient支持通过SPI的方式加载Interceptor接口的实现类,使用时只需要按照SPI的加载规则将自定义的Interceptor放入指定的目录下即可。