当前位置: 首页 > article >正文

springBoot统一响应类型3.0版本

前言:起于环境,先于实践,源于变化,升于思考,再于实践,形于总结——实践至上!

简单回顾:
/**
 * 基础统一响应类
 * @param <T>
 */

@Data
public class apiResult<T> {

    private int code;
    private String message;
    private T data;

    /**
     * 带有data返回的构造函数
     * @param code
     * @param message
     * @param data
     */
    public apiResult(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 不带data的构造函数
     * @param code
     * @param message
     */
    public apiResult(int code,String message){
        this.code = code;
        this.message = message;
    }
}

加工类

/**
 * 统一响应类实例化工具
 */

public class apiResultYOUYA {
    //http成功状态码
    private static final int OK = HttpStatus.OK.value();
    //隔着报错状态码
    private static int NO = HttpStatus.INTERNAL_SERVER_ERROR.value();

    //基本成功响应
    public static <T>apiResult<T> success(T data){
        return new apiResult<>(OK,"操作成功",data);
    }
    //自定义信息成功响应
    public static <T>apiResult<T> success(String message,T data){
        return new apiResult<>(OK,message,data);
    }
    //基础失败响应
    public static <T>apiResult<T> error(){
        return new apiResult<>(NO,"系统错误,请联系管理员");
    }
    //自定义信息失败响应
    public static <T>apiResult<T> error(String message){
        return new apiResult<>(431,message);
    }
}

测试控制类

    @GetMapping("/id")
    public apiResult<UserPageEntity> id(int id){
    UserPageEntity userPage = userPageServer.UserByID(id);
    if (userPage == null) 
        {
            return apiResultYOUYA.error("老登,没有这一号人,是不是记错了");
        }
    return apiResultYOUYA.success("成功查询,老登",userPage);

虽然不规范,但是能用

这是我们上一期对方法不生效的解释:我们并没用统一响应覆盖掉的异常报错,这只是简单的响应返回,我们响应统一覆盖掉异常报错才能做到解决

这是因为作者没有重新编译导致的问题,但是这破AI居然认可了我们这种说法,也是没谁了,最后是如何排查出问题的呢?

后来作者写3.0的内容时,顺手刷新了一下,成了

越小的错误,产生越大的bug

正片:

全局统一响应基础三步走

第一步:打上注解@ControllerAdvice

第二步:实现ResponseBodyAdvice<object>接口

第三步:重写方法

@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) {
        return false;
    }

    /**
     * HttpMessageConverter转换之前进行的操作
     * @param body 要转换的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) {
        return null;
    }
}

三步走完后,我们获取到一个基础的全局响应配置,接下在这两个方法中做文章,便可实现全局统一响应

自定义全局响应:

第一步:先将supports改为true

第二步:将body传入至我们的统一响应工具类中


@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 要转换的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(body);
    }
}

修改我们的测试controller

@RestController
public class test {

    @Resource
    UserPageServer userPageServer;

    /**
     * 自定义响应信息的运用
     *
     * @param id
     * @return
     */

    @GetMapping("/id")
    public UserPageEntity id(int id){
        
        return userPageServer.UserByID(id);
}

运行测试结果

运行前,先使用maven的claen生命周期,再编译运行,避免同上面一模一样的错误

来一个完整的增删改查,再体验体验

@RestController
@RequestMapping("/test")
public class test {

    @Resource
    UserPageServer userPageServer;


    @GetMapping("/id")
    public UserPageEntity id(int id) {
        return userPageServer.UserByID(id);
    }

    @PostMapping("/insert")
    public int insert(@RequestBody UserPageEntity userPageEntity) {
        return userPageServer.UserInsert(userPageEntity);
    }

    @PostMapping("/update")
    public int update(@RequestBody UserPageEntity userPageEntity) {
        return userPageServer.UserUpdate(userPageEntity);
    }

    @PostMapping("/delete")
    public int delete(@RequestBody Long[] id) {
        return userPageServer.USerDelete(id);
    }
}

经典永不过时

测试

无效新增

有效新增

有效查询

无效查询

无效删除

有效删除

无效更新

有效更新

经典CRUD下来,发现没,响应成功的还好说,没响应成功也套用了,也是完成了我们的目标

全局响应了

全局统一响应(无论对错)

那如果配合上局部呢?

就会因为类型的问题导致,那就修改类型

    @GetMapping("/id")
    public apiResult<UserPageEntity> id(int id) {
        UserPageEntity userPageEntity = userPageServer.UserByID(id);
        if (userPageEntity == null)
        {
            return apiResultYOUYA.error("没有该用户,老登");
        }
        return apiResultYOUYA.success("查询成功了,老登", userPageEntity);
    }

局部和全局无法同时纯在,局部>全局,就和交通法一样,地方 大于 全国

除了上面两个例子还有很多,全局作用域和局部作用域

在js中更容易体现,java还有报错

小结:如何快速达到真 · 全局统一响应(无论成功还是失败)

@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 要转换的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(body);
    }
}

第二阶段:

打上断点,测试这个方法起到的作用

当我们触发查询接口时,他自动的触发了这个方法

自动获取了接口的这6个参数

发现没,这个方法自动归类了,不知道是真是假,所以我们修改一下内容进行测试

原来如此,所谓的统一响应的来源是这个,spring web的响应内容就是由这三个大部分组成的,所谓的统一,是对接口的统一,而不是对响应内容的统一

此统一非响应统一,原因是,响应早已经是统一的了

再来一轮测试

    @GetMapping("/id")
    public UserPageEntity id(int id) {
        return userPageServer.UserByID(id);
    }

修改测试接口

通过不断的测试,测试,修改内容,作者发现了惊天的秘密(别人早在文档里就写了,你算什么发现!!!!)

下一期说明发现!


http://www.kler.cn/a/565684.html

相关文章:

  • vue的双向绑定是怎么实现的
  • 【云原生之kubernetes实战】在k8s环境中高效部署Vikunja任务管理工具(含数据库配置)
  • 【Mybatis】如何简单使用mybatis-plus,以及MybatisGenerator自动生成或者实现SQL语句
  • 嵌入式迷雾:现状谜团待解,未来行情走向何方?
  • 微信小程序读取写入NFC文本,以及NFC直接启动小程序指定页面
  • 优博讯25届春招内推
  • 武汉大学生命科学学院与谱度众合(武汉)生命科技有限公司举行校企联培座谈会
  • MQTT应用环路验证
  • Godot4.3 显示像素风格图片模糊如何设置?
  • Debian安装C语言环境
  • 自主可控:国产CAE一体化平台如何筑基新能源车未来
  • leetcode 75.颜色分类(详解)数组分块c++
  • 【Spring】AOP
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_t
  • [深度学习] 大模型学习2-提示词工程指北
  • 【落羽的落羽 C++】C++入门基础·其之一
  • 芯麦GC1277:电脑散热风扇驱动芯片的优质之选 并可替代传统的0CH477/灿瑞芯片。
  • API,URL,Token,XML,JSON是干嘛的
  • 某镇江 app 练手
  • linux之crosstool-NG(1)生成toolchain