注解式参数校验--validate

注解式参数校验--validate

依赖

SpringBoot version >= 2.3没有集成javax.validation,在pom.xml中引入以下依赖即可:

  • springboot 项目
<!-- 参数校验 javax.validation -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  • spring 应用单独使用
<!--注解式参数校验-->
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>7.0.0.Final</version>
</dependency>
<!--注解式参数校验-->

spring 注入校验器:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

实战

@Data
public class User {
    private String id;
    @NotBlank(message = "用户名不能为空")
    private String username;
    @NotBlank(message = "密码不能为空")
    private String password;
    @Email(message = "Email格式错误")
    private String email;
    @PastOrPresent(message = "日期小于等于当前时间")
    private Date birthday;
    @Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$", message = "手机号格式错误")
    private String phone;
    @Min(value = 0, message = "年龄超出范围,最小值为0")
    @Max(value = 120, message = "年龄超出范围,最大值为120")
    private Integer age;
}
  • controller接口上使用@Valid(或@Validated)使得校验生效:
public void addUser(@Valid @RequestBody User user)
  • 全局异常处理:

相当于是拦截validation框架抛出的异常,对这个异常做处理

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.bind.support.WebExchangeBindException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 全局异常处理
 *
 * @author ming
 * @version 1.0.0
 * @date 2022/3/27 0:06
 **/

@Slf4j
@RestControllerAdvice
public class ExampleGlobalExceptionHandler {
    
    @ExceptionHandler(WebExchangeBindException.class)
    public Map<String, Object> handle(WebExchangeBindException exception) {
        // 这里最好使用一个统一的返回对象
        // 获取参数校验错误集合
        List<FieldError> fieldErrors = exception.getFieldErrors();
        // 格式化以提供友好的错误提示
        String data = String.format("参数校验错误(%s):%s", fieldErrors.size(),
                fieldErrors.stream()
                        .map(FieldError::getDefaultMessage)
                        .collect(Collectors.joining(";")));
        // 参数校验失败响应失败个数及原因
        Map<String, Object> map = new HashMap<>(3);
        map.put("code", exception.getStatus().value());
        map.put("message", exception.getStatus());
        map.put("data", data);
        return map;
    }
}

自定义校验器

  • 校验器自定义注解
import com.jd.work.example.validator.PhoneValidator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 手机号参数校验注解
 *
 * @author ming
 * @version 1.0.0
 * @date 2022/3/27 0:14
 **/

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE,
        ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {
    String message() default "手机号码格式错误";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
  • 校验器实现
import com.jd.work.example.annotations.Phone;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * 自定义手机号码参数校验器
 *
 * @author ming
 * @version 1.0.0
 * @date 2022/3/27 0:15
 **/

public class PhoneValidator implements ConstraintValidator<Phone, Object> {
    private static final String PHONE_REGEX = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$";

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
        //值不为空或者满足正则表达式时返回true
        return Objects.isNull(value) || Pattern.compile(PHONE_REGEX).matcher(value.toString()).find();
    }
}

注解

注解 描述
@AssertFalse 所注解的元素必须是Boolean类型,且值为false
@AssertTrue 所注解的元素必须是Boolean类型,且值为true
@DecimalMax 所注解的元素必须是数字,且值小于等于给定的值
@DecimalMin 所注解的元素必须是数字,且值大于等于给定的值
@Digits 所注解的元素必须是数字,且值必须是指定的位数
@Future 所注解的元素必须是将来某个日期
@Max 所注解的元素必须是数字,且值小于等于给定的值
@Min 所注解的元素必须是数字,且值小于等于给定的值
@Range 所注解的元素需在指定范围区间内
@NotNull 所注解的元素值不能为null
@NotBlank 所注解的元素值有内容
@Null 所注解的元素值为null
@Past 所注解的元素必须是某个过去的日期
@PastOrPresent 所注解的元素必须是过去某个或现在日期
@Pattern 所注解的元素必须满足给定的正则表达式
@Size 所注解的元素必须是String、集合或数组,且长度大小需保证在给定范围之内
@Email 所注解的元素需满足Email格式
posted @ 2022-03-27 00:17  itwetouch  阅读(649)  评论(0编辑  收藏  举报