注解式参数校验--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格式 |