Spring Boot在内部通过集成hibernate-validation实现了JSR-349验证规范接口,我们可以在MVC模式中对DTO进行灵活的校验,代码看起来也会更简洁、更优雅.
参考地址:https://docs.jboss.org/hibernate/stable/validator/reference/en-US/pdf/hibernate_validator_reference.pdf
常用注解列表
@AssertTrue | 用于boolean字段,该字段只能为true |
---|---|
@AssertFalse | 该字段的值只能为false |
@CreditCardNumber | 对信用卡号进行一个大致的验证 |
@DecimalMax | 只能小于或等于该值 |
@DecimalMin | 只能大于或等于该值 |
@Digits(integer=,fraction=) | 检查是否是一种数字的整数、分数,小数位数的数字 |
检查是否是一个有效的email地址 | |
@Future | 检查该字段的日期是否是属于将来的日期 |
@Length(min=,max=) | 检查所属的字段的长度是否在min和max之间,只能用于字符串 |
@Max | 该字段的值只能小于或等于该值 |
@Min | 该字段的值只能大于或等于该值 |
@NotNull | 不能为null |
@NotBlank | 不能为空,检查时会将空格忽略 |
@NotEmpty | 不能为空,这里的空是指空字符串 |
@Null | 检查该字段为空 |
@Past | 检查该字段的日期是在过去 |
@Pattern(regex=,flag=) | 被注释的元素必须符合指定的正则表达式 |
@Range(min=,max=,message=) | 被注释的元素必须在合适的范围内 |
@Size(min=, max=) | 检查该字段的size是否在min和max之间,可以是字符串、数组、集合、Map等 |
@URL(protocol=,host,port) | 检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件 |
@Valid | 该注解主要用于字段为一个包含其他对象的集合或map或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象 |
maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!--Jackson,用于前端传过来的json字符串,对其序列号和反序列化-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
controller控制层
package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.model.Result;
import com.example.demo.model.Student;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
public class ValidationItemException {
@PostMapping(value = "/validation/save")
public Result saveStudentPage(@Valid @RequestBody Student student) {
return new Result(200, "", JSONObject.toJSON(student).toString());
}
@PostMapping(value = "/validation/save2")
public Student saveStudentPage2(@Valid @RequestBody Student student) {
return student;
}
}
DTO实体层(Student)
1.错误信息统一管理
我们也可以把错误信息message定制化到配置文件message.properties里面统一管理
2.@Valid和@Validated的区别
@Valid是javax.validation里的 @Validated是@Valid 的一次封装,是Spring提供的校验机制使用。@Validated 提供分组功能,但是在校验项比较多的情况下,本人不是很推荐分组校验,因为在开发中容易出错.
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Future;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
public class Student {
@Range(min=15,max=65,message = "年龄必须在15岁到65岁")
private int age;
@Size(min=2, max=30)
private String name;
@NotEmpty(message = "自定义错误信息,score不能为空!")
private String score;
@Future(message = "生效时间必须大于当前时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getScore() {
return score;
}
public void setScore(String score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", score='" + score + '\'' +
'}';
}
}
DTO实体层(Result)
package com.example.demo.model;
public class Result implements java.io.Serializable{
private int code;
private String msg;
private Object data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
全局异常捕获
package com.example.demo.Hanlder;
import com.example.demo.model.Result;
import org.springframework.http.HttpStatus;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.List;
import java.util.stream.Collectors;
@RestControllerAdvice
public class BindExceptionHandler {
/**
* 全局异常捕捉处理
*
* @param ex
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleBindException(MethodArgumentNotValidException ex) {
// 同样是获取BindingResult对象,然后获取其中的错误信息
// 如果前面开启了fail_fast,事实上这里只会有一个信息
//如果没有,则可能又多个
List<String> errorInformation = ex.getBindingResult().getAllErrors()
.stream()
.map(ObjectError::getDefaultMessage)
.collect(Collectors.toList());
return new Result(HttpStatus.BAD_REQUEST.value(),errorInformation.toString(),null) ;
}
}