springBoot统一响应类型3.2版本
springBoot统一响应类型3.2版本
前言:
通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往复以至无穷,而实践和认识之每一循环的内容,都比较地进到了高一级的程度。
简单回顾3.1版本的内容:
1:@ControllerAdvice提供了对全局统一响应支持
2:supports与beforBodyWrite关系,用一个三元写法,supports ? beforBodyWrite :异常
正片:
进行基于以下代码,进行更加全面的测试
@ControllerAdvice public class GlobalApiResult implements ResponseBodyAdvice<Object> { /** * 此Advice是否使用于该返回类型和Converter类型(意思是可以配置多个哦) * @param returnType 返回类型(这里可以获取很多东西, 别被名字误导了) * @param converterType 自动选择的转换器类型 * @return 返回true表示将会走接下来的方法(beforeBodyWrite), 否则不会 */ @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { //false -> true 用于测试,正式的时需要修改 return true; } /** * HttpMessageConverter转换之前进行的操作 * @param body 业务层接口返回值 * @param returnType 返回类型 * @param selectedContentType 根据请求头协商的ContentType * @param selectedConverterType 自动选择的转换器类型 * @param request 当前请求 * @param response 当前响应 * @return 返回至前端的数据,参数为,形参 */ @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { //第二步: 将body传入统一响应工具类中的默认成功响应 return apiResultYOUYA.success("3.0全新版本",body); } }
对supports和beforeBodyWrite打上断点
触发接口时,supports通过MethodParameter自动捕获接口类型
2.就是一个包的路径,不做过多内容
supports,通过MethodParameter获取接口类型,也就是说它并没有做过多的接口处理
spring web 是如何使用这个接口的呢?
这个方法
AbstractJackson2HttpMessageConverter.class.isAssignableFrom(converterType)
翻译:如下
- 判断此 {@code Class} 对象所表示的类或接口是否与指定的 {@code Class} 参数所表示的类或接口相同,或是其父类或父接口。若是则返回 {@code true};否则返回 {@code false}。若此 {@code Class} 对象表示基本类型,则当且仅当指定的 {@code Class} 参数与此 {@code Class} 对象完全相同时返回 {@code true},否则返回 {@code false}。
结合代码
AbstractJackson2HttpMessageConverter.class.isAssignableFrom(converterType)
if( AbstractJackson2HttpMessageConverter.class ? converterType)
?是代码这isAssignableFrom的判断逻辑
isAssignableFrom有两种判断逻辑
第一种:判断接口是否相同(继承的继承实现接口也算)
第二种:判断是否是同一个对象
Class<? extends HttpMessageConverter<?>>
父的实现 等于 字的实现
也就是说,在官方的用法中,他们进行了接口判断,放回为true,那我们在实践开发中,也可以仿照官方写法
那就要回到开始,support究竟实现了什么?
判断了一下Class> converterType与AbstractJackson2HttpMessageConverter是否实现了同一个接口
第二个实现
经典的,继承的继承实现 越多于 我实现了
不管它的逻辑是什么,最终返回的都是一个true OR false
怎么写都无所谓,只要结果为true就会运行beforeBodyWriteInternal方法
例如,用户没有vip,我们除了在业务层进行判断,还能在哪里进行判断呢?
supports这里进行判断,if(x != vip){ false },你查出数据又如何,我不给你看,无敌~~~~
常规写法是拦截器,业务判断,没想到把,还能通过限制响应完成
很显然,并不能通过在supports中进行业务判断
直接给false
该成功还是成功
所以得出结论
support只影响下面的beforeBodyWrite,不影响整个
@Nullable public Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { Iterator var6 = this.getMatchingAdvice(parameter, RequestBodyAdvice.class).iterator(); while(var6.hasNext()) { RequestBodyAdvice advice = (RequestBodyAdvice)var6.next(); if (advice.supports(parameter, targetType, converterType)) { body = advice.handleEmptyBody(body, inputMessage, parameter, targetType, converterType); } } return body; }
这段代码就是supports怎么连接beforeBodyWrite的
看见没,很简单的一个循环 + 判断,完成了spring web的响应配上一个注解,便可实现全局统一响应
总结:
supports只影响同一文件下的beforeBodyWrite,所以不要想着用这玩意限制vip用户
判断外面是循环,而不是循环在判断里面
supports ?beforeBodyWrite :异常