【spring】参数校验Validation

embedded/2025/1/2 16:52:48/

前言

在实际开发中,我们无法保证客户端传来的请求都是合法的。比如一些要求必传的参数没有传递,传来的参数长度不符合要求等,这种时候如果放任不管,继续执行后续业务逻辑,很有可能就会出现意想不到的bug。

有人可能会说,这不是前端的问题吗,让前端校验去。话是这么说,但我们也不能前端校验百分百不会出现问题。并且有些请求可能也不是正规通过客户端发来的,可能是黑客恶意攻击,又或是通过Postman等发来的,这些请求就不一定会“合法”了。

因此,对客户端传来的每个请求都进行必要的参数校验是十分重要的。而很多简单的校验如果都需要程序员自己去写的话,就会导致代码过于冗长、繁琐。为了让校验更加简洁明了,Spring为我们提供了Validation工具类来提供各种校验方法。

一、Validation常见的校验注解

空校验注解

  • @Null:被注释的元素必须为null
  • @NotNull:被注释的元素必须不为null
  • @NotBlank:被注释的字符串去掉前后空格后长度必须非零。
  • @NotEmpty:被注释的字符串、集合或数组不能为空(字符串长度非零、集合大小非零)。

布尔校验注解

  • @AssertTrue:被注释的元素必须为true
  • @AssertFalse:被注释的元素必须为false

日期校验注解

  • @Past:被注释的元素必须是一个过去的日期。
  • @Future:被注释的元素必须是一个将来的日期。

数字校验注解

  • @Min(value):被注释的元素必须是一个数字,其值必须大于等于指定的最小值。
  • @Max(value):被注释的元素必须是一个数字,其值必须小于等于指定的最大值。
  • @DecimalMin(value):被注释的元素必须是一个数字,其值必须大于等于指定的最小值。
  • @DecimalMax(value):被注释的元素必须是一个数字,其值必须小于等于指定的最大值。

长度校验注解

  • @Size(max, min):被注释的元素(如字符串、集合、数组)的大小必须在指定的范围内。

模式匹配校验注解

  • @Pattern(regexp):被注释的元素必须符合指定的正则表达式。

邮箱校验注解

  • @Email:被注释的元素必须是电子邮箱地址。

范围校验注解

  • @Range(min, max):被注释的元素必须在合适的范围内。

二、Validation的简单应用

首先我们需要导入Validation的依赖:

<!--validation依赖,负责参数校验-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>

接着在需要使用校验的类上添加@Validation注解

接着主要有两种方式使用校验注解:

1、直接在对应参数上加上注解

@RestController
@RequestMapping("/user")
@Validation
public class UserController {@RequestMapping("/login")public Result login(@Size(max = 12,min = 4) String username, @Pattern(regexp = "^\S{5,16}$") String password){//登录return Result.success();}}

2、实体类添加校验

对于一些实体类来说,直接在参数上加注解就不太可取了,程序会无法定位到指定参数。

需要再实体类内部对应的变量上添加注解:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Category {@NotNullprivate Integer id;//主键ID@NotEmptyprivate String categoryName;//分类名称@NotEmptyprivate String categoryAlias;//分类别名private Integer createUser;//创建人ID@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//创建时间@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime updateTime;//更新时间
}

接着在使用实体类的地方加上 @Validated 注解,就能让这些校验生效了:

@PutMapping("/update")public Result update(@RequestBody @Validated User user){//业务逻辑return Result.success();}

二、分组校验

前面我们介绍了如何在实体类中添加校验注解。但是,事实上在实现不同功能时,对同一个实体类的校验规则可能是会有差异的。

比如在添加用户的场景下,用户的id值就是在存入数据库后生成的,在参数传递时自然就不是必传项;而在更新用户的场景下,我们需要通过id定位指定用户,完成信息更新操作,这时在参数传递时id就是必传项了。

这样,对id值的校验就会产生冲突了。如果将id设定为必传值,那么就会导致添加用户的操作可能出现错误。不把id设定为必传值,更新用户的操作又会出现错误。

为了应对这一问题,就可以对校验项进行分组归类。具体操作步骤如下:

在实体类内部定义相应组别接口:

public class User {//各成员变量//添加用户类分组public interface Add extends Default {}//更新用户类分组public interface Update extends Default{}
}

注意:如果没有手动对校验项进行分组,其默认就在 Default

对校验项进行分组,只需要通过groups属性指定组别即可:

@NotNull(groups = Update.class)

接着在校验时指定对应的分组即可:

@PutMapping
public Result update(@RequestBody @Validated(User.Update.class) User user){//业务逻辑return Result.success();
}@PostMapping
public Result add(@RequestBody @Validated(User.Add.class) User user){//业务逻辑return Result.success();
}

这样就能实现不同业务场景下的多样化校验了。

三、自定义校验

实际开发中的校验规则可能是五花八门的,但官方提供的校验注解就这么多,很多时候并不能满足我们的校验需求。这时候就需要通过自定义校验注解来实现个性化的校验了。

首先需要定义一个注解:

@Documented //元注解
@Target(ElementType.FIELD) //元注解
@Retention(RetentionPolicy.RUNTIME) //元注解
@Constraint(validatedBy = {/*校验规则*/}) //自定义校验规则
public @interface State {//提供校验失败后的提示信息String message() default "state参数的值只能是已发布或草稿";//指定分组Class<?>[] groups() default {};//负载  获取到State注解的附加信息Class<? extends Payload>[] payload() default {};
}

接着定义一个类去实现 ConstraintValidator 接口,并实现 isValid 方法:

public class StateValidation implements ConstraintValidator<State,String> {@Overridepublic boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {//返回true表示校验通过,返回false则表示校验不通过if(value==null) return false;if(value.equals("已发布")||value.equals("草稿"))return true;return false;}
}

然后就要在之前定义的注解中的@Constraint中填入自定义类:

@Constraint(validatedBy = {StateValidation.class}) //自定义校验规则

接着就可以像使用其它校验注解一样来使用自己自定义的注解了:


那么本篇文章就到此为止了,如果觉得这篇文章对你有帮助的话,可以点一下关注和点赞来支持作者哦。如果有什么讲的不对的地方欢迎在评论区指出,希望能够和你们一起进步


http://www.ppmy.cn/embedded/150279.html

相关文章

替代传统FTP传输,镭速大数据传输系统实现安全高效数据流转!

信息技术的快速进步让大数据成为了企业决策的关键支撑&#xff0c;但同时也带来了巨大的挑战。企业在运营过程中产生的数据量急剧增加&#xff0c;这对数据传输的速度、安全性和效率提出了更高的要求。然而&#xff0c;传统的FTP传输方式在处理大规模数据时显得力不从心&#x…

Word批量更改公式字体为Times New Roman

文章目录 单个公式修改修改所有公式VBA批量修改 在写毕业论文的时候&#xff0c;往往要求公式使用Times New Roman字体&#xff0c;但这种字体并不是专门为了公式设计的&#xff0c;所以并不支持在公式中直接调用。 单个公式修改 由于数学公式中有大量数学符号&#xff0c;所…

从 Elastic 迁移到 Easysearch 指引

从 Elasticsearch 迁移到 Easysearch 需要考虑多个方面&#xff0c;这取决于当前使用的 Elasticsearch 版本、能容忍的停机时间、应用需求等。在此背景下&#xff0c;我们梳理了一下通用的升级指引&#xff0c;方便大家进行迁移工作。 迁移路径 Elasticsearch 版本快照兼容推…

IS-2T2R存储器:AWS精度下降问题的解决方案

在本篇中&#xff0c;我们将介绍《An isolated symmetrical 2T2R cell enabling high precision and high density for RRAM-based in-memory computing》这篇文献&#xff0c;它提出了一种对称式的2T2R忆阻器结构&#xff0c;通过引入隔离晶体管解决了传统2T2R忆阻器非对称结构…

科伦川宁生物:绿色科技引领,双翼齐飞筑梦未来

在探索生命奥秘与绿色未来的征途中&#xff0c;一家企业正以科技之光&#xff0c;照亮生物发酵与合成生物学的融合之路&#xff0c;引领着一场前所未有的产业革命。今天&#xff0c;让我们一同走进科伦药业子公司川宁生物的世界&#xff0c;见证其如何用绿色科技和创新力量&…

vue3学习笔记(10)-$subscribe,store组合式写法

1.$subscribe订阅&#xff0c;监视vuex中数据得修改 2.localStorage里面穿的都是字符串&#xff0c;关掉浏览器数据还在 只能获取字符串&#xff0c;用ts语法写明&#xff0c;作为字符串使用 3.组合式写法

Mac 安装 php-redis扩展

1.确认系统是否安装homebrew&#xff0c;如果没有就去安装一个&#xff0c;别犟&#xff0c;好用&#xff1b; 2.安装redis brew install redis 3.下载redis编译安装或pcel直接安装&#xff0c;两种方法大家自己试一下&#xff0c;我使用的pcel没有成功 /*** 下载redis扩展*…

PyTorch快速入门教程【小土堆】之池化层

视频地址神经网络-最大池化的使用_哔哩哔哩_bilibili kernel_size (Union[int, Tuple[int, int]]) –要占用的最大窗口的大小stride (Union[int, Tuple[int, int]]) –窗户的步长。默认是kernel_sizepadding (Union[int, Tuple[int, int]]) –隐式负无穷大填充将被添加到两边d…