Spring Validation使用小结

1、背景

Spring 框架,广泛应用于 JAVA 企业级开发中,包含了一套实用的字段校验机制: Spring Validation。这个机制融合了 JSR380 规范,即 Bean Validation 2.0。本文将介绍 Spring Validation 的使用方法,包括基础注解的应用以及进阶使用技巧。

2、常用注解

2.1、Bean Validation 2.0 注解

2.1.1、校验空值

  • @Null:验证对象是否为 null
  • @NotNull:验证对象是否不为 null
  • @NotEmpty:验证对象不为 null,且长度(数组、集合、字符串等)大于 0
  • @NotBlank:验证字符串不为 null,且去除两端空白字符后长度大于 0

2.1.2、校验大小

  • @Size(min=, max=):验证对象(数组、集合、字符串等)长度是否在给定的范围之内
  • @Min(value):验证数值(整数或浮点数)是否大于等于指定的最小值
  • @Max(value):验证数值是否小于等于指定的最大值

2.1.3、校验布尔值

  • @AssertTrue:验证 Boolean 对象是否为 true
  • @AssertFalse:验证 Boolean 对象是否为 false

2.1.4、校验日期和时间

  • @Past:验证 Date 和 Calendar 对象是否在当前时间之前
  • @Future:验证 Date 和 Calendar 对象是否在当前时间之后
  • @PastOrPresent:验证日期是否是过去或现在的时间
  • @FutureOrPresent:验证日期是否是现在或将来的时间

2.1.5、正则表达式

  • @Pattern(regexp=, flags=):验证 String 对象是否符合正则表达式的规则

2.1.5.1、验证IP地址

    @Pattern(regexp = "(((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d))", message = "IP地址不合法")
    private String ip;

2.1.5.1、验证手机号码

    @Pattern(regexp = "^(13[0-9]|14[5-9]|15[0-3,5-9]|16[6]|17[0-8]|18[0-9]|19[8,9])\\d{8}$", message = "手机号不合法")
    private String username;

3、 使用

3.1、当方法入参为 @PathVariable、 @RequestParam 注解的简单参数时,需要在 Controller 加上 @Validated 注解开启校验

@RestController
@Validated // 必须加上该注解
public class UserController {

  // 路径变量
  @GetMapping("{id}")
  public Reponse<NoticeDTO> detail(@PathVariable("id") @Min(1L) Long noticeId) {
    return Reponse.ok();
  }

  // 请求参数
  @GetMapping("getByTitle")
  public Result getByTitle(@RequestParam("title") @Length(min = 1, max = 20) String  title) {
    return Result.ok();
  }
}

3.2、当方法入参为 @RequestBody 注解的 JavaBean,可在入参前使用 @Validated 注解开启校验

@PostMapping("/save")
public Response<Boolean> execute(@Validated @RequestBody NoticeDTO noticeDTO) {
  return Response.ok(true);
}

4、参数不合法提示

import java.util.List;
import java.util.Objects;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.cnblogs.javalouvre.http.Result;
import com.cnblogs.javalouvre.http.ResultEnum;

@RestControllerAdvice
public class GlobalExceptionAdvice {

    /**
     * {@code @org.springframework.web.bind.annotation.PathVariable} 和 {@code @org.springframework.web.bind.annotation.RequestParam} 参数校验不通过时抛出的异常处理
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<?> handleConstraintViolationException(ConstraintViolationException e) {
        final Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        if (!CollectionUtils.isEmpty(constraintViolations)) {
            for (ConstraintViolation<?> constraintViolation : constraintViolations) {
                return Result.failure(ResultEnum.PARAM_IS_INVALID, constraintViolation.getMessage());
            }
        }

        return Result.failure(ResultEnum.PARAM_IS_INVALID);
    }

    /**
     * {@code @org.springframework.web.bind.annotation.RequestBody} 参数校验不通过时抛出的异常处理
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        final BindingResult bindingResult = e.getBindingResult();
        if (Objects.nonNull(bindingResult)) {
            final List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            if (!CollectionUtils.isEmpty(fieldErrors)) {
                for (FieldError fieldError : fieldErrors) {
                    return Result.failure(ResultEnum.PARAM_IS_INVALID, fieldError.getDefaultMessage());
                }
            }
        }

        return Result.failure(ResultEnum.PARAM_IS_INVALID);
    }

}

posted @ 2023-12-21 13:39  Bruce.Chang.Lee  阅读(24)  评论(0编辑  收藏  举报