本文实例讲述了spring boot validation参数校验。分享给大家供大家参考,具体如下:
对于任何一个应用而言在客户端做的数据有效性验证都不是安全有效的,这时候就要求我们在开发的时候在服务端也对数据的有效性进行验证。 Spring Boot自身对数据在服务端的校验有一个比较好的支持,它能将我们提交到服务端的数据按照我们事先的约定进行数据有效性验证。
1 pom依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
2 校验使用实例
- 配置要验证的请求实体
public class User { @Null private Long id; @NotBlank private String name; @Email private String email; // 省略getter和setter }
- 控制器方法配置
@PostMapping("/addUser") public String addUser(@Valid @RequestBody User user){ ... }
- 校验失败统一处理
校验失败时将抛出MethodArgumentNotValidException异常
/** * 全局Exception处理 * * @author liusq * */ @RestControllerAdvice public class GlobalExceptionHandler { private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class); @SuppressWarnings("rawtypes") @ExceptionHandler(value = Exception.class) public ResponseEntity handle(Exception e) { if (e instanceof MethodArgumentNotValidException) { BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult(); if (bindingResult.hasErrors() && bindingResult.hasFieldErrors()) { FieldError fieldError = bindingResult.getFieldError(); BodyValidStatus bodyValidStatus = new BodyValidStatus.Builder().code("0009") .message(fieldError.getDefaultMessage()) .field(fieldError.getField()).build(); LOGGER.warn(bodyValidStatus.getMessage() + e); return new ResponseEntity<>(bodyValidStatus, HttpStatus.OK); } else { bodyStatus = DataUtil.bodyStatus("0009"); } } else { bodyStatus = DataUtil.bodyStatus(Constants.ERROR_CODE); } LOGGER.error(bodyStatus.getMessage() + e); return new ResponseEntity<>(bodyStatus, HttpStatus.OK); } } public class BodyValidStatus { // 错误代码 private String code; // 错误代码解释 private String message; // 错误字段 private String field; public BodyValidStatus() { } public BodyValidStatus(String code, String message, String field) { this.code = code; this.message = message; this.field = field; } private BodyValidStatus(Builder builder) { setCode(builder.code); setMessage(builder.message); setField(builder.field); } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getField() { return field; } public void setField(String field) { this.field = field; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } public static final class Builder { private String code; private String message; private String field; public Builder() { } public Builder code(String val) { code = val; return this; } public Builder message(String val) { message = val; return this; } public Builder field(String val) { field = val; return this; } public BodyValidStatus build() { return new BodyValidStatus(this); } } }
3 验证注解详解
验证注解
验证的数据类型
说明
空检查
@Null
任意类型
验证注解的元素值是null
@NotNull
任意类型
验证注解的元素不是null
@NotBlank
CharSequence子类型(CharBuffer、String、StringBuffer、StringBuilder)
验证注解的元素值不为空(不为null、去除首尾空格后长度不为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的首尾空格
@NotEmpty
CharSequence子类型、Collection、Map、数组
验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
Boolean检查
@AssertFalse
Boolean,boolean
验证注解的元素值是false
@AssertTrue
Boolean,boolean
验证注解的元素值是true
长度检查
@Size(min=下限, max=上限)
字符串、Collection、Map、数组等
验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小
@Length(min=下限, max=上限)
CharSequence子类型
验证注解的元素值长度在min和max区间内
日期检查
@Past
java.util.Date,java.util.Calendar;Joda Time类库的日期类型
验证注解的元素值(日期类型)比当前时间早
@Future
与@Past要求一样
验证注解的元素值(日期类型)比当前时间晚
数值检查
@MIN(value=值)
BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存储的是数字)子类型
验证注解的元素值大于等于@Min指定的value值
@MAX(value=值)
和@Min要求一样
验证注解的元素值小于等于@Max指定的value值
@DecimalMin(value=值)
和@Min要求一样
验证注解的元素值大于等于@ DecimalMin指定的value值
@DecimalMax(value=值)
和@Min要求一样
验证注解的元素值小于等于@ DecimalMax指定的value值
@Digits(integer=整数位数, fraction=小数位数)
和@Min要求一样
验证注解的元素值的整数位数和小数位数上限
@Range(min=最小值, max=最大值)
BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型
验证注解的元素值在最小值和最大值之间
其他检查
@Valid
任何非原子类型
指定递归验证关联的对象;如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加@Valid注解即可级联验证
@Pattern(regexp=正则表达式,flag=标志的模式)
CharSequence的子类型
验证注解的元素值与指定的正则表达式匹配
@Email(regexp=正则表达式,flag=标志的模式)
CharSequence的子类型
验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式
@CreditCardNumber
CharSequence的子类型
验证注解元素值是信用卡卡号
@ScriptAssert(lang= ,script=)
业务类
校验复杂的业务逻辑
4 自定义验证注解和验证规则
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; import com.xxx.xxx.constraint.impl.MoneyValidator; @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy=MoneyValidator.class) public @interface Money { String message() default"不是金额形式"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } import java.util.regex.Pattern; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import com.xxx.xxx.constraint.Money; public class MoneyValidator implements ConstraintValidator<Money, Double> { private String moneyReg = "^\\d+(\\.\\d{1,2})?$";//表示金额的正则表达式 private Pattern moneyPattern = Pattern.compile(moneyReg); public void initialize(Money money) { // TODO Auto-generated method stub } public boolean isValid(Double value, ConstraintValidatorContext arg1) { // TODO Auto-generated method stub if (value == null) return true; return moneyPattern.matcher(value.toString()).matches(); } }
更多关于java相关内容感兴趣的读者可查看本站专题:《Spring框架入门与进阶教程》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。