• ResponseBodyAdvice接口使用导致的报错及解决


    一、ResponseBodyAdvice使用

    ResponseBodyAdvice用于在返回值写入响应之前,将body的内容重新封装,直接上代码

    1.1 CommonResponseDataAdvice

    @Component
    public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> {
        private static final String V_3_API_DOCS = "/v3/api-docs";
        private static final String SWAGGER_RESOURCES = "/swagger-resources";
        private static final String ADMIN_ACTUATOR = "/actuator";
    
        public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
            if (methodParameter.getAnnotatedElement().isAnnotationPresent(IgnoreResponseAdvice.class)) {
                return false;
            } else {
                return !methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class);
            }
        }
    
        @Nullable
        public Object beforeBodyWrite(@Nullable Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
            //避免对swagger的api接口返回值进行封装
            if (((ServletServerHttpRequest) serverHttpRequest).getServletRequest().getRequestURI().equals(V_3_API_DOCS)) {
                return o;
            }
            if (((ServletServerHttpRequest) serverHttpRequest).getServletRequest().getRequestURI().contains(SWAGGER_RESOURCES)) {
                return o;
            }
            //避免对actuator的监控接口进行封装
            if (((ServletServerHttpRequest) serverHttpRequest).getServletRequest().getRequestURI().contains(ADMIN_ACTUATOR)) {
                return o;
            }
            if (o instanceof Result) {
                return o;
            }
            return new Result<>(0, "",o);
    
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    关键方法beforeBodyWrite,在SpringMVC主流程有讲到
    在这里插入图片描述
    它将被调用,从而将返回值封装到自定义的Result里面,方便前端统一处理状态码。

    二、报错及解决

    2.1 集成swagger报错

    在集成swagger之后,始终报错,接口文档出不来,出现如下错误信息:

    Unable to render this definition
    The provided definition does not specify a valid version field.
    Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: “2.0” and those that match openapi: 3.0.n (for example, openapi: 3.0.0).

    百度了半天没有用,最后检查/v3/api-docs接口发现返回值被封装之后,swagger的前端无法解析自定义的结构,导致报错。
    解决方案: 判断特定的接口路径不做封装

    2.2 接口直接返回String类型报错

    定义一个接口

    @GetMapping("/getUserName")
        @ApiOperation("根据ID获取用户")
        public String getUserName() {
            return "username";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用Swagger发送请求
    在这里插入图片描述
    报错了,说是Result无法强转为String,没办法只能从源码找解决方案,根据SpringMVC主流程,关键地方还是在这里
    在这里插入图片描述
    Spring提供了10个消息转换器,String在Json的前面。调用beforeBodyWrite方法之后
    在这里插入图片描述
    先匹配到转换器StringHttpMessageConverter,又将body封装成Result类型
    在这里插入图片描述
    StringHttpMessageConverter的泛型是String,进入write方法之后
    在这里插入图片描述
    t的类型是Result,子类中的addDefaultHeaders方法需要的是String
    在这里插入图片描述
    导致类型强转异常
    解决方案: 接口的返回String类型时,提前用Result封装。不能在beforeBodyWrite判断是StringHttpMessageConverter就不封装,因为StringHttpMessageConverter转换完就返回,Json转换器就用不上了。

    @GetMapping("/getUserName")
        @ApiOperation("根据ID获取用户")
        public Result<String> getUserName() {
            return new Result<>("username");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    java-php-python-ssm学生综合测评系统计算机毕业设计
    SpringBoot的自动装配源码分析(2022.11.07)
    浅谈匈牙利算法(二分图最大匹配)
    Spring Authorization Server(AS)从 Mysql 中读取客户端、用户
    电力系统iec103通信
    CarSim仿真快速入门(十八)-CarSim2021中的混合动力和纯电动系统
    Flink-源算子Source(获取数据源)的使用
    Day.js 常用方法 以后再也不用new Date( )啦
    Leetcode 剑指 Offer II 050. 路径总和 III
    Python学习第1天:Python和Vscode环境安装
  • 原文地址:https://blog.csdn.net/yx444535180/article/details/125911407