上述代码实现中,针对前面提到的 MsgBody对象类型进行了拦截处理。
在beforeBodyRead 中,返回一个BodyInputMessage对象,而这个对象便负责源数据流解析转换
代码说明
完成数据流的转换,包括以下步骤:
获取请求内容字符串;
构建 MsgBody 对象,将内容字符串作为其 content 字段;
将 MsgBody 对象 Json 序列化,再次转成字节流供后续环节使用。
ResponseBodyAdvice 用法ResponseBodyAdvice 的用途在于对返回内容做拦截处理,如下面的示例:
@ControllerAdvice(assignableTypes = InterceptController.class) public static class CustomResponseAdvice implements ResponseBodyAdvice<String> { private static final Logger logger = LoggerFactory.getLogger(CustomRequestAdvice.class); @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { // 返回true,表示启动拦截 return true; } @Override public String beforeBodyWrite(String body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { logger.info("CustomResponseAdvice beforeBodyWrite"); // 添加前缀 String raw = String.valueOf(body); return "PREFIX:" + raw; } }看,还是容易理解的,我们在返回的字符串中添加了一个前缀!
推荐指数
2 颗星,这是两个非常冷门的接口,目前的使用场景也相对有限;
一般在需要对输入输出流进行特殊处理(比如加解密)的场景下使用。
这是目前最灵活的做法,直接利用注解可实现任意对象、方法的拦截。
在某个Bean的类上面** @Aspect** 注解便可以将一个Bean 声明为具有AOP能力的对象。
简单说明
@Pointcut 用于定义切面点,而使用target关键字可以定位到具体的类。
@Around 定义了一个切面处理方法,通过注入ProceedingJoinPoint对象达到控制的目的。
一些常用的切面注解:
注解 说明@Before 方法执行之前
@After 方法执行之后
@Around 方法执行前后
@AfterThrowing 抛出异常后
@AfterReturing 正常返回后
深入一点
aop的能力来自于spring-boot-starter-aop,进一步依赖于aspectjweaver组件。
有兴趣可以进一步了解。
推荐指数
5颗星,aspectj 与 SpringBoot 可以无缝集成,这是一个经典的AOP框架,
可以实现任何你想要的功能,笔者之前曾在多个项目中使用,效果是十分不错的。
注解的支持及自动包扫描大大简化了开发,然而,你仍然需要先对 Pointcut 的定义有充分的了解。
到这里,读者可能想知道,这些实现拦截器的接口之间有什么关系呢?
答案是,没有什么关系! 每一种接口都会在不同的时机被调用,我们基于上面的代码示例做了日志输出:
可以看到,各种拦截器接口的执行顺序如下图: