概述:
@Valid是使用Hibernate validation的时候使用
@Validated是只用Spring Validator校验机制使用
说明:java的JSR303声明了@Valid这类接口,而Hibernate-validator对其进行了实现
@Validation对@Valid进行了二次封装,在使用上并没有区别,但在分组、注解位置、嵌套验证等功能上有所不同,这里主要就这几种情况进行说明
注解位置:
@Validated:用在类型、方法和方法参数上。但不能用于成员属性(field)
@Valid:可以用在方法、构造函数、方法参数和成员属性(field)上
配置异常处理器
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 异常处理器
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 请求方式不支持
*/
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
@ResponseStatus(code = HttpStatus.METHOD_NOT_ALLOWED)
public R handleException(HttpRequestMethodNotSupportedException e) {
logger.error(e.getMessage(), e);
return R.error("不支持' " + e.getMethod() + "'请求");
}
@ExceptionHandler(Exception.class)
public R handleException(Exception e) throws Exception {
logger.error(e.getMessage(), e);
return R.error("服务器错误,请联系管理员");
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public R handleValidException(MethodArgumentNotValidException e){
//日志记录错误信息
String defaultMessage = e.getBindingResult().getFieldError().getDefaultMessage();
log.error("=================校验器触发错误================" + defaultMessage);
//将错误信息返回给前台
return R.error(defaultMessage);
}
}
验证注解的类型
注解 | 含义 |
---|---|
@Null | 只能为null |
@NotNull | 必须不为null |
@Max(value) | 必须为一个不大于 value 的数字 |
@Min(value) | 必须为一个不小于 value 的数字 |
@AssertFalse | 必须为false |
@AssertTrue | 必须为true |
@DecimalMax(value) | 必须为一个小于等于 value 的数字 |
@DecimalMin(value) | 必须为一个大于等于 value 的数字 |
@Digits(integer,fraction) | 必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Past | 必须是 日期 ,且小于当前日期 |
@Future | 必须是 日期 ,且为将来的日期 |
@Size(max,min) | 字符长度必须在min到max之间 |
@Pattern(regex=,flag=) | 必须符合指定的正则表达式 |
@NotEmpty | 必须不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 必须不为空(不为null、去除首位空格后长度不为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
必须为Email,也可以通过正则表达式和flag指定自定义的email格式 |
例子
@size (min=3, max=20, message=“用户名长度只能在3-20之间”)
@size (min=6, max=20, message=“密码长度只能在6-20之间”)
@pattern (regexp="[a-za-z0-9._%±]+@[a-za-z0-9.-]+\.[a-za-z]{2,4}", message=“邮件格式错误”)
@Length(min = 5, max = 20, message = “用户名长度必须位于5到20之间”)
@Email(message = “比如输入正确的邮箱”)
@NotNull(message = “用户名称不能为空”)
@Max(value = 100, message = “年龄不能大于100岁”)
@Min(value= 18 ,message= “必须年满18岁!” )
@AssertTrue(message = “bln4 must is true”)
@AssertFalse(message = “blnf must is falase”)
@DecimalMax(value=“100”,message=“decim最大值是100”)
@DecimalMin(value=“100”,message=“decim最小值是100”)
@NotNull(message = “身份证不能为空”)
@Pattern(regexp="^(\d{18,18}|\d{15,15}|(\d{17,17}[x|X]))$", message=“身份证格式错误”)
在实体类上添加校验规则
@Data
@Entity
public class BookKeeping implements Serializable {
@NotBlank(message = "记账类型不能为空!")
private String bookType;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date bookTime;
@Min(value = 18, message = "年龄不能小于18岁", groups = {IGroupB.class})
private Integer age;
@Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误")
private String phoneNum;
@Email(message = "邮箱格式错误")
private String email;
@Pattern(regexp = "^[0-9]+(.[0-9]{1,2})?$", message = "金额格式不对")
@NotBlank(message = "付款单金额不能为空")
@Length(max = 16, message = "付款单金额超过最大长度")
private String costFee;
}
在方法对应的实体前加上 @Validated 就可以了
@RestController
@RequestMapping("keeping")
public class BookKeepingController {
@PostMapping("save")
public R addSave(@RequestBody @Validated BookKeeping bookKeeping) {
// 这样就可以快乐的玩耍了
}