Spring MVC 校验

艺帆风顺 发布于 2025-04-03 22 次阅读


在日常开发中,我们经常会遇到各种通用的校验场景,比如字段非空校验、字段长度校验等。下面将详细介绍 Spring MVC 中的校验相关内容。

常见校验注解

注解描述
@Null被注释的元素必须为 null
@NotNull被注释的元素不能为 null
@AssertTrue该字段只能为 true
@AssertFalse该字段的值只能为 false
@Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(“value”)被注释的元素必须是一个数字,验证小数的最小值
@DecimalMax(“value”)被注释的元素必须是一个数字,验证小数的最大值
@Size(max, min)检查该字段的 size 是否在 min 和 max 之间,可以是字符串、数组、集合、Map 等
@Past被注释的元素必须是一个过去的日期
@Future被注释的元素必须是一个将来的日期
@Pattern(regexp = “[abc]”)被注释的元素必须符合指定的正则表达式
@Email被注释的元素必须是电子邮件地址
@Length(max = 5, min = 1, message = “长度在 1~5”)检查所属的字段的长度是否在 min 和 max 之间,只能用于字符串
@NotEmpty被注释的字符串必须非空
@Range被注释的元素必须在合适的范围内
@NotBlank不能为空,检查时会将空格忽略
@NotEmpty不能为空,这里的空是指空字符串

下面我们来看具体的校验实现方式。

两种校验方式

1. @Validated + BindingResult 控制器校验

这种方式中,请求实体与 BindingResult 一一对应。需要添加以下依赖:

  1.     javax.validation
  2.     validation-api
  3.     2.0.1.Final
  4.     org.springframework.boot
  5.     spring-boot-starter-validation

实体类示例

  1. import lombok.Data;
  2. import lombok.ToString;
  3. import javax.validation.constraints.NotBlank;
  4. @Data
  5. @ToString
  6. public class ReqDTO {
  7.     @NotBlank(message = "param1 不能为空")
  8.     private String param1;
  9.     @NotBlank(message = "param2 不能为空")
  10.     private String param2;
  11.     @NotBlank(message = "param3 不能为空")
  12.     private String param3;
  13. }

控制器示例

  1. @RestController
  2. public class MyController {
  3.     @PostMapping("/param1")
  4.     public String param1(@Validated @RequestBody ReqDTO reqDTO, BindingResult bindingResult) {
  5.         if (bindingResult.hasErrors()) {
  6.             FieldError fieldError = bindingResult.getFieldError();
  7.             assert fieldError != null;
  8.             return fieldError.getDefaultMessage();
  9.         }
  10.         return "success";
  11.     }
  12. }

2. 自定义 Validator 校验工具类

此方式不局限于控制器层,可在任何地方使用。

工具类代码

  1. @Component
  2. public class ParamCheckUtil {
  3.     private static Validator validator;
  4.     @Autowired
  5.     private Validator injectValidator;
  6.     @PostConstruct
  7.     public void preInit() {
  8.         validator = injectValidator;
  9.     }
  10.     public static T> String checkByGroupsGetOneMessage(T t, Class>... groups) {
  11.         if (t == null) {
  12.             return null;
  13.         }
  14.         SetConstraintViolationT>> validate = validator.validate(t, groups);
  15.         if (validate.size() == 0) {
  16.             return null;
  17.         }
  18.         return validate.stream().findFirst().get().getMessage();
  19.     }
  20.     public static T> String checkByGroupsGetAllMessage(T t, Class>... groups) {
  21.         if (t == null) {
  22.             return null;
  23.         }
  24.         SetConstraintViolationT>> validate = validator.validate(t, groups);
  25.         if (validate.size() == 0) {
  26.             return null;
  27.         }
  28.         ListString> msgList = new ArrayList();
  29.         validate.forEach(cv -> msgList.add(cv.getMessage()));
  30.         return String.join(";", msgList);
  31.     }
  32. }

应用示例

  1. @RestController
  2. public class MyController {
  3.     @PostMapping("/param2")
  4.     public String param2(@RequestBody ReqDTO reqDTO) {
  5.         String message = ParamCheckUtil.checkByGroupsGetAllMessage(reqDTO);
  6.         if (message != null) {
  7.             return message;
  8.         }
  9.         return "success";
  10.     }
  11. }

其他扩展校验 - 分组校验

当一个实体类应用于多个场景的请求入参,且入参要求不同时,我们可以给校验属性添加分组,默认分组是 Default

实体类示例

  1. @Data
  2. @ToString
  3. public class GroupReqDTO {
  4.     @NotBlank(message = "param1 不能为空")
  5.     private String param1;
  6.     @NotBlank(message = "param2 不能为空", groups = A.class)
  7.     private String param2;
  8.     @NotBlank(message = "param3 不能为空", groups = B.class)
  9.     private String param3;
  10.     public interface A {}
  11.     public interface B {}
  12. }

控制器示例

  1. @RestController
  2. public class MyController {
  3.     @PostMapping("/param4")
  4.     public String param4(@Validated({GroupReqDTO.A.class}) @RequestBody GroupReqDTO reqDTO, BindingResult bindingResult) {
  5.         if (bindingResult.hasErrors()) {
  6.             FieldError fieldError = bindingResult.getFieldError();
  7.             assert fieldError != null;
  8.             return fieldError.getDefaultMessage();
  9.         }
  10.         return "success";
  11.     }
  12. }

通过以上内容,我们全面了解了 Spring MVC 中的校验机制,包括常见注解、两种校验方式以及分组校验的使用方法。