Spring Boot 2.x Validation参数校验

编写接口时,为防止非法参数对业务造成影响,需要在Controller层添加参数校验。通过javax.validation的一系列注解可以帮助我们完成参数校验,免去繁琐的逻辑判断。

依赖

根据JSR 380规范,validation-api依赖中包含标准的参数验证API:

Bean Validation 2.0 版本需要Java 8或更高版本。

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.2.Final</version>
</dependency>

Hibernate Validator是参数验证API的具体实现。

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.7.Final</version>
</dependency>

在Spring Boot 2.3.x之前,以上依赖在spring-boot-starter-web中自动引入。 Spring Boot 2.3.x之后,需要手动引入。

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

使用场景

入参为实体对象

当入参为实体对象时,在对象上添加@Validated注解,并且实体属性上添加约束注解(如@Size等) 就能实现参数的自动校验。

  1. 实体对象添加@Validated注解
public R<Boolean> save(@RequestBody @Validated User user) {}
  1. 实体属性上添加约束注解。
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraints.Email;

public class User {
    
    @NotNull(message = "用户名称不能为空")
    private String name;

    @AssertTrue
    private boolean working;

    @Size(min = 6, max = 20, message 
      = "密码长度必须是6-20个字符")
    private String password;

    @Min(value = 18, message = "年龄最小不超过18")
    @Max(value = 150, message = "年龄最大不超过150")
    private int age;

    @Email(message = "邮箱格式不正确")
    private String email;

    // ...
}
  1. 如果不符合验证要求,则将注解属性message的信息作为响应提示信息。
{
    "code": 400,
    "success": true,
    "data": null,
    "msg": "用户名称不能为空"
}

全局异常拦截

添加参数检验全局拦截处理类

@RestControllerAdvice
@Configuration
public class CommonExceptionHandler {

 /**
     * 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R<Object> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(","));
        return R.fail(ResultCode.PARAM_MISS, message);
    }

    /**
     * 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
     */
    @ExceptionHandler(BindException.class)
    public R<Object> bindExceptionHandler(BindException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(","));
        return R.fail(ResultCode.PARAM_MISS, message);
    }

    /**
     * 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是ConstraintViolationException
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public R constraintViolationExceptionHandler(ConstraintViolationException e) {
        String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(","));
        return R.fail(ResultCode.PARAM_MISS, message);
    }

}

注解

注解支持验证类型说明
@Null任意类型验证带注解的属性值是null。
@NotNull任意类型验证带注解的属性值不为null。
@NotEmptyString、 Collection、 Map或Array验证带注解的属性值不为null或空。
@NotBlankString验证带注解的属性值不为null或空字符,只针对字符串检验。
@AssertTrueBoolean验证带注解的属性值是true。
@AssertFalseBoolean验证带注解的属性值是false。
@SizeString、 Collection、 Map或Array验证带注解的属性值的大小介于属性min和max之间。
@DigitsBigDecimal、BigInteger、CharSequence、byte, short, int, long以及它们的封装类型验证带注解的属性值是可接受范围内的数字。
@MinBigDecimal、BigInteger、byte, short, int, long以及它们的封装类型验证带注解的属性值不小于@Min指定的value值。
@Max同@Min要求验证带注解的属性值不大于@Max指定的value值。
@DecimalMin同@Digits要求验证带注解的属性值不小于@DecimalMin指定的value值。
@DecimalMax同@Digits要求验证带注解属性值不大于@DecimalMax指定的value值。
@Positive同@Min要求验证带注解的属性值是正数。
@PositiveOrZero同@Min要求验证带注解的属性值是正数或0。
@Negative同@Min要求验证带注解的属性值是负数。
@NegativeOrZero同@Min要求验证带注解的属性值是负数或0。
@Pastjava.util.Date、java.util.Calendar、java.time验证带注解的属性值为过去时间(比当前时间早)。
@PastOrPresent同@Past要求验证带注解的属性值为过去时间(比当前时间早)或当前时间。
@Future同@Past要求验证带注解的属性值为未来时间(比当前时间晚)。
@FutureOrPresent同@Past要求验证带注解的属性值为未来时间(比当前时间晚)或当前时间。
@PatternString验证带注解的属性值与指定的正则表达式匹配。
@EmailString验证带注解的属性值是有效的电子邮件地址。

个人博客 > 欢迎来访

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏叶新城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值