注解式参数校验@Valid,拒绝if-else炼狱

2024-01-09 04:52

本文主要是介绍注解式参数校验@Valid,拒绝if-else炼狱,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

        在软件开发中,与客户进行数据的交互是比较频繁的数据采集方式,而为了确保数据的正确落库,数据校验的部分必不可少。参数校验具体指的是对输入数据的大小、类型、正则匹配等对数据本身属性的校验,这一块的校验通常是在前端进行第一轮校验,确保参数具备一定逻辑正确性才将其打包至后端处理,而为了进一步增强安全性,也同样需要在后端板块进行二次校验。而对于此类校验,最常见也是最臃肿的处理方案就是if-else炼狱,如果说参数个数较少,那么无可厚非,但如果包含了七八个参数,那么这就很拉跨了,下面介绍一种基于注解的校验方案,进一步优化校验参数代码的可读性。


效果演示

本例子基于通过在实体类映射接收请求参数的MVC接口,对实体类中需要对属性进行如下验证:

  • name - 用户姓名,不能为空;

  • age - 年龄,大于0小于20;

  • phone - 手机号,满足手机号格式;

实体类代码

 @Datapublic class TestPojo {@NotBlank(message = "不满足时抛出的自定义异常回馈信息")private String name;@Min(value = 0, message = "不满足时抛出的自定义异常回馈信息")@Max(value = 20, message = "不满足时抛出的自定义异常回馈信息")private Integer age;@Pattern(regexp = "^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(147))\d{8}$", message = "不满足时抛出的自定义异常回馈信息")private String phone;}

业务接口

@PostMapping("/test")
public ResultVO test(@Valid @RequestBody TestPojo testPojo) {// 直接写业务代码,无需编写if-else校验....return ResultVO.ok("响应数据");}

结果VO类

@Data
public class ResultVO<T> implements Serializable {private int code;private boolean success;private T data;private String msg;
​private ResultVO(int code, T data, String msg) {this.code = code;this.data = data;this.msg = msg;this.success = code == 200;}
​public static <T> ResultVO<T> ok(T data) {return new ResultVO<>(200, data, null);}
​public static <T> ResultVO<T> error(String msg) {return new ResultVO<>(500, null, msg);}
}

全局异常处理类

@RestControllerAdvice
public class GlobalExceptionHandler {/*  *  这里的BindException不是自定义的,是该参数校验框架自带的*  当设置的参数规则不满足,就会抛出该类型的异常,并且把不满足的哪个校验参数自定义的异常信息封装到该对象中*/@ExceptionHandler(BindException.class)  public ResultVO handleError(BindException e) {BindingResult bindingResult = e.getBindingResult();return R.error(bindingResult.getFieldError().getDefaultMessage());}
}

        通过以上代码,就可以实现对接收的请求数据的参数校验,并且当校验失败就会抛出指定异常被异常处理类进行捕捉处理,返回自定义的不满足参数所对应的自定义提示信息


快速使用

引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>

编写校验实体类

        其实这一块和上方"结果VO类"的演示中可以了解到使用的方式,咱主要要知道它有哪些常用的校验注解可以使用就好

常用注解作用解释
@NotNull值不能为null
@NotEmpty字符串、集合或数组的值不能为空,即长度大于0
@NotBlank字符串的值不能为空白,即不能只包含空格
@Size字符串、集合或数组的大小是否在指定范围内
@Min数值的最小值
@Max数值的最大值
@DecimalMin数值的最小值,可以包含小数
@DecimalMax数值的最大值,可以包含小数
@Pattern字符串是否匹配指定的正则表达式

还有许多有关的校验可以自行查询,这里不作过多赘述

校验失败异常捕获处理

@RestControllerAdvice
public class GlobalExceptionHandler {/*  *  这里的BindException不是自定义的,是该参数校验框架自带的*  当设置的参数规则不满足,就会抛出该类型的异常,并且把不满足的哪个校验参数自定义的异常信息封装到该对象中*/@ExceptionHandler(BindException.class)  public ResultVO handleError(BindException e) {BindingResult bindingResult = e.getBindingResult();String 自定义的不满足参数校验结果信息 = bindingResult.getFieldError().getDefaultMessage();}
}

启用校验

其实就是在接收实体类上加一个@Valid注解就可以启用实体类中校验逻辑

@PostMapping("/test")
public void test(@Valid @RequestBody TestPojo testPojo) {// 直接写业务代码,无需编写if-else校验....}

        也许会有疑惑,一个实体类我不一定要用来校验数据呀,这样子设置后会不会以后用这个实体类都要进行参数校验了?并不会,不想校验就不要加@Valid注解就完事了嘛


总结

        通过以上的方案,我们可以较为简洁实现简单的参数校验,为shi山的削减贡献了一份力量,当然,我们会发现通过这种方案,我们能够校验的方式实际上是比较单薄的,往往我们需要针对项目业务需求对参数进行一些自定义的校验逻辑,那么这点可以参考我写的另一篇文章:基于 AOP + 自定义注解 的校验业务讲解,希望本文对大家有所帮助。

这篇关于注解式参数校验@Valid,拒绝if-else炼狱的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/585979

相关文章

Spring中@Lazy注解的使用技巧与实例解析

《Spring中@Lazy注解的使用技巧与实例解析》@Lazy注解在Spring框架中用于延迟Bean的初始化,优化应用启动性能,它不仅适用于@Bean和@Component,还可以用于注入点,通过将... 目录一、@Lazy注解的作用(一)延迟Bean的初始化(二)与@Autowired结合使用二、实例解

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

Idea实现接口的方法上无法添加@Override注解的解决方案

《Idea实现接口的方法上无法添加@Override注解的解决方案》文章介绍了在IDEA中实现接口方法时无法添加@Override注解的问题及其解决方法,主要步骤包括更改项目结构中的Languagel... 目录Idea实现接China编程口的方法上无法添加@javascriptOverride注解错误原因解决方

Java通过反射获取方法参数名的方式小结

《Java通过反射获取方法参数名的方式小结》这篇文章主要为大家详细介绍了Java如何通过反射获取方法参数名的方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、解决方式方式2.1: 添加编译参数配置 -parameters方式2.2: 使用Spring的内部工具类 -

Java中基于注解的代码生成工具MapStruct映射使用详解

《Java中基于注解的代码生成工具MapStruct映射使用详解》MapStruct作为一个基于注解的代码生成工具,为我们提供了一种更加优雅、高效的解决方案,本文主要为大家介绍了它的具体使用,感兴趣... 目录介绍优缺点优点缺点核心注解及详细使用语法说明@Mapper@Mapping@Mappings@Co

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

MySQL中时区参数time_zone解读

《MySQL中时区参数time_zone解读》MySQL时区参数time_zone用于控制系统函数和字段的DEFAULTCURRENT_TIMESTAMP属性,修改时区可能会影响timestamp类型... 目录前言1.时区参数影响2.如何设置3.字段类型选择总结前言mysql 时区参数 time_zon

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去