Spring Boot参数校验实现自定义响应类优雅处理

news2024/10/7 8:24:48
😊 @ 作者: 一恍过去
💖 @ 主页: https://blog.csdn.net/zhuocailing3390
🎊 @ 社区: Java技术栈交流
🎉 @ 主题: Spring Boot参数校验实现自定义响应类优雅处理
⏱️ @ 创作时间: 2023年08月03日

在这里插入图片描述

目录

    • 目的:
      • 操作方式
      • @valid基本注解
      • 准备内容
      • 实现
        • 方法一:AOP、
        • 方式二:全局异常拦截(推荐)
      • 补充

目的:

对前端请求的数据进行格式、长度、是否为空等进行校验,可以防止脏数据对数据库的影响。

操作方式

通过在controller中加入@valid对请求参数进行校验

  • 方式一、配合AOP实现
  • 方式二、配合全局异常实现

@valid基本注解

常用主要注解如下:

注解作用参数
@Null验证是否为nullmessage=“返回信息”
@NotNull验证是否不为null, 无法查检长度为0的字符串message=“返回信息”
@NotBlank验证是否不为null, 并且不会过滤空格字符串message=“返回信息”
@NotEmpty验证String是否为null,或者对象是否emptymessage=“返回信息”
@Min参数必须大于等于该值value=数值,message=“返回信息”
@Max参数必须小于等于该值value=数值,message="返回信息
@Pattern参数必须满足正则表达式regexp=“正则”,message="返回信息
@Email参数必须为电子邮箱message=“返回信息”
@Valid对关联对象进行递归校验-
@Range验证数字的最大值与最小值min=, max=
@Size验证对象(Array,Collection,Map,String)长度最大值与最小值min=, max=
@Length验证String的长度最大值与最小值min=, max=

准备内容

pom:

<dependency>
   <groupId>jakarta.validation</groupId>
   <artifactId>jakarta.validation-api</artifactId>
</dependency>

0、响应类

public class ResponseObject {
    private Integer status;
    private Object data;
    private String message;

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public static ResponseObject failure(String message) {
        ResponseObject responseObject = new ResponseObject();
        responseObject.setStatus(500);
        responseObject.setData(false);
        responseObject.setMessage(message);
        return responseObject;
    }
}

1、实体类


public class User implements Serializable {


    /**
     * 用户名
     */
    @NotEmpty(message = "不能为空")
    private String username;

    @Max(value = 20, message = "不能超过20")
    @Min(value = 10, message = "不能小于10")
    private Integer num;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }
}

2、Controller

@RestController
public class UserController {
    @ParamValid
    @GetMapping("/get")
    public ResponseObject getUser(@Valid User user, BindingResult bindingResult) {
        return ResponseObject.failure("");
    }

    @PostMapping("/post")
    public ResponseObject postUser(@Valid @RequestBody User user) {
        return ResponseObject.failure("");
    }
}

3、自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamValid {

}

4、AOP类

@Component
@Aspect
public class ParameterValidAop {
    @Before("@annotation(paramValid)")
    public void paramValid(JoinPoint point, ParamValid paramValid) throws Exception {
        Object[] paramObj = point.getArgs();
        for (Object obj : paramObj) {
            if (obj instanceof BindingResult) {
                BindingResult result = (BindingResult) obj;
                if (result.hasErrors()) {
                    List<ObjectError> allErrors = result.getAllErrors();
                    //返回第一个错误
                    String defaultMessage = allErrors.get(0).getDefaultMessage();
                    throw new Exception(defaultMessage);
                }
            }
        }
    }
}

5、全局异常

 @RestControllerAdvice
@Slf4j
public class GlobalException {
    /**
     * 参数校验异常
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseObject handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();

        // 所有参数异常信息
        List<ObjectError> allErrors = bindingResult.getAllErrors();

        return ResponseObject.failure(allErrors.get(0).getDefaultMessage());
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(BindException.class)
    public ResponseObject handlerBindException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();

        // 所有参数异常信息
        List<ObjectError> allErrors = bindingResult.getAllErrors();

        return ResponseObject.failure(allErrors.get(0).getDefaultMessage());
    }
}

实现

方法一:AOP、

在controller中加入@Valid、 @ParamValid注解,以及BindingResult参数

@ParamValid
    @GetMapping("/get")
    public ResponseObject getUser(@Valid User user, BindingResult bindingResult) {
        return ResponseObject.failure("");
    }

通过postman访问conrtoller地址,写入的参数并且不满足规则,可以看到会抛出错误异常
在这里插入图片描述
可以看到在抛出的异常中,并是不自己定义的格式,如果想要返回自定义的响应实体,需要在全局异常中写一个自定义异常,并且获取在AOP中抛出的差异,是不是觉得有点麻烦,在用的AOP以后,还需要进行额外的代码操作,所以推荐第二中方式,直接使用全局异常进行拦截 ,并且返回自定义响应。

方式二:全局异常拦截(推荐)

controller如下:

@GetMapping("/get")
    public ResponseObject getUser(@Valid User user) {
        return ResponseObject.failure("");
    }

    @PostMapping("/post")
    public ResponseObject postUser(@Valid @RequestBody User user) {
        return ResponseObject.failure("");
    }

进行请求
在这里插入图片描述
可以看到控制台打印了错误信息,意思就是如果出现了不满足条件的参数请求,会自动抛出异常,那么我们就可以在自定义异常中进行捕获,代码看上面(5、全局异常)。
最后返回结果,就是自己打印的数据格式:
在这里插入图片描述

补充

可以将所有错误提示一起返回

					List<ObjectError> allErrors = result.getAllErrors();
 
                    //装载为集合
                    List<ObjectError> allErrors = result.getAllErrors();
                    List<String> lists = new ArrayList<>();
                    for (ObjectError objectError : allErrors) {
                        lists.add(objectError.getDefaultMessage());
                    }

参考:@1nchaos https://www.cnblogs.com/1nchaos/p/11442559.html

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/831121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

模拟考试系统与传统教育方法的对比分析

随着科技的不断进步&#xff0c;教育领域也在不断更新和发展。模拟考试系统作为一种新的教育方式&#xff0c;与传统的教育方法相比&#xff0c;在学习效果、学习方式和学习体验等方面具有诸多优势。 学习效果 模拟考试系统能够提供更全面、更真实的考试环境&#xff0c;从而…

使用mysql容器创建主从同步

1、主数据库设置 创建主数据库容器&#xff1a; docker run -d --restartalways --name mysql-master -p 3306:3306 -v /home/apps/mysql-master/conf:/etc/mysql/conf.d -v /home/apps/mysql-master/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD123456 mysql:8.0.16 --lower…

【普通人维护windows的方法,不中毒,不弹窗,不卡顿】

前言 IT人也是普通人&#xff0c;我就说说普通人维护电脑的方法。 我的电脑配置 给大家看看&#xff0c;配置一般&#xff0c;运行软件和游戏&#xff0c;可以保持基本流程 日常维护措施 我不太喜欢设定一些非主流的配置&#xff0c;下了一个360卫士,360其他的套餐可以不用下…

【腾讯云 Cloud Studio 实战训练营】云上编程,彻底释放电脑物理内存

文章目录 前言一、快速上手1、账号注册2、新建工作空间3、配置工作空间参数4、工作空间展示5、运行飞机大战代码 二、空间模板三、应用推荐1、点击 Fork2、等待工作空间启动3、安装 Dependencies4、运行 App 总结 前言 腾讯云推出的 Cloud Studio 是基于浏览器的集成式开发环境…

Android 14重要更新预览

Android 14重要更新预览 国际化 Android 14 在 Android 13 的基础上进一步扩展了按应用设定语言功能&#xff0c;提供了一些额外的功能&#xff1a; 自动生成应用的 localeConfig&#xff1a;从 Android Studio Giraffe Canary 7 和 AGP 8.1.0-alpha07 开始&#xff0c;您可以…

vcruntime140_1.dll修复的方法大全,缺失vcruntime140_1.dll解决方法分享

vcruntime140_1.dll这个文件在电脑里属于挺重要的一个文件&#xff0c;一但它缺失了&#xff0c;那么很多程序都是运行不了的&#xff0c;今天我们就来讲解一下这个vcruntime140_1.dll修复以及它的一些作用和属性。 一.vcruntime140_1.dll的作用 vcruntime140_1.dll是Microso…

排序八卦炉之选择、堆排

文章目录 1.选择排序1.1代码实现1.2复杂度 2.堆排序2.1代码实现2.2复杂度 1.选择排序 1.1代码实现 // 当数据趋于有序或随机(可能部分有序) 插排更有优势 O(N)~O(N^2) //选择排序&#xff1a;O&#xff08;N^2&#xff09; O(N^2)~O(N^2) void …

HttpRunner自动化工具之times 重复执行

单个用例重复执行 如果想让某个测试步骤重复执行&#xff0c;可以在test 中增加times参数&#xff0c;如下: 执行效果&#xff1a; 实战案例 光学理论是没用的&#xff0c;要学会跟着一起敲&#xff0c;要动手实操&#xff0c;才能将自己的所学运用到实际当中去&#xff0c;这…

纯粹即刻,畅享音乐搜索的轻松体验

纯粹即刻&#xff0c;畅享音乐搜索的轻松体验 在当今快节奏的生活中&#xff0c;我们常常渴望一种简单而便捷的方式来探索和享受音乐。现在&#xff0c;你可以纯粹即刻地畅享音乐搜索的轻松体验。无论你是寻找热门歌曲还是探索不同风格的音乐&#xff0c;这款应用将为你带来随…

6.物联网操作系统信号量

一。信号量的概念与应用 信号量定义 FreeRTOS信号量介绍 FreeRTOS信号量工作原理 1.信号量的定义 多任务环境下使用&#xff0c;用来协调多个任务正确合理使用临界资源。 2.FreeRTOS信号量介绍 Semaphore包括Binary&#xff0c;Count&#xff0c;Mutex&#xff1b; Mutex包…

ATFX汇评:英央行利率决议来袭,大概率加息25基点

ATFX汇评&#xff1a;今日19:00&#xff0c;英国央行公布利率决议、会议纪要和货币政策报告&#xff1b;半小时后&#xff0c;英国央行行长贝利召开货币政策新闻发布会。当前英国央行基准利率5%&#xff0c;市场预期将加息25基点至5.25%&#xff0c;假若符合预期&#xff0c;则…

问道管理:沪指窄幅震荡跌0.18%,有色、汽车等板块走低

3日早盘&#xff0c;沪指盘中窄幅震动下探&#xff0c;创业板逆市上扬&#xff1b;两市半日成交不足5000亿元&#xff0c;北向资金净卖出超15亿元。 到午间收盘&#xff0c;沪指跌0.18%报3255.88点&#xff0c;深成指跌0.23%&#xff0c;创业板指涨0.2%&#xff1b;两市算计成交…

2023年一建考点速记(五大专业)

一级级建造师考点速记手册是根据历年考试的命题方向及命题规律总结而成&#xff0c;其中BI超频必考点(每年必考)&#xff0c;B2高频易考点(每2年一次)B3中频可考点(3-5年一次)&#xff0c;B4低频 BOSS 考点(超过5年一次B1涵盖卷面的40%的分值;B2涵盖卷面20%的分值;B3涵盖卷面15…

网工头疼的IP子网划分,其实就这么简单

下午好&#xff0c;我的网工朋友。 最近网工群里还是一如既往的热闹啊&#xff0c;关于行业、技术、职场的话题热议不断。 前段时间有群友在里面聊子网划分&#xff0c;有几个不懂的网工朋友&#xff0c;悄悄来私聊老杨总&#xff0c;表示想再补充一下这方面的知识。 看了眼&…

IDEA强大的VisualGC插件

前言 开发阶段实时监测&#xff0c;自己的JVM信息&#xff0c;实时可视化 Hotspot JVM 垃圾回收监控工具, 支持查看本地和远程JVM进程, 支持G1 and ZGC算法。 插件安装 在线安装 IntelliJ IDEA 可通过在线安装的方式&#xff0c;安装插件 JDK VisualGC&#xff0c;安装步骤: …

Selenium Chrome Webdriver 如何获取 Youtube 悬停文本

导语 Youtube 是一个非常流行的视频分享平台&#xff0c;有时候我们可能想要爬取一些视频的信息&#xff0c;比如标题、播放量、点赞数等。但是有些信息并不是直接显示在网页上的&#xff0c;而是需要我们将鼠标悬停在某个元素上才能看到&#xff0c;比如视频的时长、上传时间…

华为云CTS 使用场景

云审计服务 CTS 云审计服务&#xff08;Cloud Trace Service&#xff09;&#xff0c;帮助您监控并记录华为云账号的活动&#xff0c;包括通过控制台、API、开发者工具对云上产品和服务的访问和使用行为&#xff0c;提供对各种云资源操作记录的收集、存储和查询功能&#xff0…

解密Redis:应对面试中的缓存相关问题2

面试官&#xff1a;Redis集群有哪些方案&#xff0c;知道嘛&#xff1f; 候选人&#xff1a;嗯~~&#xff0c;在Redis中提供的集群方案总共有三种&#xff1a;主从复制、哨兵模式、Redis分片集群。 面试官&#xff1a;那你来介绍一下主从同步。 候选人&#xff1a;嗯&#xff…

IDEA基础使用

IDEA基础使用 1、IDEA中显示用法和用户截图展示有调用显示无调用显示 对应方法 2、如何找出项目中所有不被调用方法截图展示对应方法 3、常用代码(Code)说明及快捷键:4、未完待续待日后更新。。。总结&#xff1a;欢迎指导&#xff0c;也祝码友们代码越来越棒&#xff0c;技术越…

python版puppeteer——pyppeteerselenium的加强版——seleniumwire

目录 前言seleniumwire安装创建web driver设置代理反屏蔽修改window.navigator.webdriver关键字返回结果options追加参数 pyppeteerpuppeteer安装快速入门参数配置隐藏浏览器特征拦截请求更多文档&博客 Playwright安装快速入门新概念&#xff1a;Context页面基本操作选择器…