1、拦截器
拦截器 | 类型 | 作用于 | 备注标记 |
---|---|---|---|
Filter | interface | servlet | *1 |
@Aspect | annotation | 方法 | *2 |
HandlerInterceptor | interface | @Controller/@RestController | *1 |
@ControllerAdvice | annotation | 仅定义 @Component | |
RequestBodyAdvice | interface | @RequestBody | *3 |
RequestBodyAdviceAdapter | abstract | @RequestBody | *3 |
ResponseBodyAdvice | interface | @ResponseBody | *3 |
2、注意事项
- *1 如读取输入流,会引发流读尽(EOF)的问题
- *2 可直接获取参数,避免输入流读尽的问题
- *3 无输入流读尽问题
3、使用情况
对特点的 Controller 记录 request 或 response,但不同的 Controller,有不同的参数表达和记录需要,他们也存在 Url、QueryString、Header 和 Body。
-
- @RequestBody 型的 json body 业务
- HttpServletRequest 直接使用 request
- @PathVariable 使用路径参数
- @RequestParam 使用request参数
- @ModelAttribute 使用bind对象的
4、一般用法
其中比较隐蔽且常见的问题,就是一但需要记录 body 内容,不管是 request 还是 response,都会引发流被读尽(EOF)的问题,若是部分读取,就会破坏业务数据的完整性。
-
- Filter-这个最重,处理所有 servlet,属于底层接口,慎用。
- @Aspect-对方法参数处理时使用,会比 MVC 多一层 AOP
- HandlerInterceptor-对 Controller 时使用,比 Filter 轻
- XXXBodyAdvice-仅对 @XxxBody注解的参数有效
5、总结
因此,根据业务规模,吞吐量,需要选择不同的拦截层面,简单高效的处理数据,不多不少,刚刚好即可。
重点要区分是否读取 body。
-
- 如果需要且是 @XXXBody 注解的,就使用 XXXBodyAdvice 省事。
- 如果还需要方法的参数,使用 @Aspect 处理(都是spring bind后的)。
- 如果要原始数据,就 HttpServletRequest 记录完整请求。
文章评论