@Validated :绑定需要校验的数据.
数据校验规则:为数据绑定校验的规则
private Long booId;
@NotNull(message = "不能为空")
private String bookName;
private String author;
private String publisher;
@DecimalMin(value = "20",message = "不能低于20元")
@DecimalMax(value = "100",message = "不能多于100")
private Float price;
//正则表达式检验
//正则表达式用来判断某个字符串是否符合某个规则
//或者用来提取一整个字符 串中满足某个规则的子串
@Pattern(regexp = "1[345678][0-9]{9}")
private String Mobile;
为是实体类属性绑定检验规则:
message为检验不合格时的提示信息.
import javax.validation.constraints.*; public class BookBean { private Long booId; @NotNull(message = "书名不能为空") private String bookName; private String author; private String publisher; @DecimalMin(value = "20",message = "不能低于20元") @NotNull(message = "价格不能为空") @DecimalMax(value = "100",message = "不能多于100") private Float price; //正则表达式检验 //正则表达式用来判断某个字符串是否符合某个规则 //或者用来提取一整个字符 串中满足某个规则的子串 @Pattern(regexp = "1[345678][0-9]{9}") private String Mobile;public String getIdCard() { return idCard; } public void setIdCard(String idCard) { this.idCard = idCard; } public String getMobile() { return Mobile; } public void setMobile(String mobile) { Mobile = mobile; } public Long getBooId() { return booId; } public void setBooId(Long booId) { this.booId = booId; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPublisher() { return publisher; } public void setPublisher(String publisher) { this.publisher = publisher; } public Float getPrice() { return price; } public void setPrice(Float price) { this.price = price; } }
绑定数据检验:
注意:校验结果:BindingResult result必须经跟在@Validated BokBean bokBean 后面.用于接受检验的结果.
@RequestMapping("/book/creat") public String create(@Validated BokBean bokBean, BindingResult result, Model model){ //可以通过BindingResult对象拿到校验的错误信息. //注意:该参数必须要紧跟在被校验的对象的后面 if (result.hasErrors()){ //判断是否有检验的错误 // result.getFieldError("bookName").getDefaultMessage(); for (FieldError error : result.getFieldErrors()) { //获取被校验对象的所有错误 String message = error.getDefaultMessage(); System.out.println(message); } //可以直接把错误信息的集合都放到集合里 model.addAttribute("erros", result.getFieldErrors()); return "erro"; } return "success"; }
自定义检验规则,有时候spring自带的检验规则不满足我们使用时,可以自定义检验规则.
检验规则:
public class IDValidator implements ConstraintValidator<IDVlidation,String> { @Override public boolean isValid(String value, ConstraintValidatorContext context) { //这里引用了一个身份证检验的工具类 return IdCardUtils.isIDCard(value); }
//这个方法可不实现 @Override public void initialize(IDVlidation constraintAnnotation) { } }
自定义一个检验规则的注解,自定义注解见自定义注解章节:https://www.cnblogs.com/zhouchangyang/p/10908343.html
定义这个注解为了方便,可仿造spring定义的注解规则写(赋值粘贴)
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) //表明该注解可用在哪里 @Retention(RUNTIME) //表明生效时间 @Repeatable(IDVlidation.List.class) @Constraint(validatedBy = {IDValidator.class}) //注明该注解所实现的规则是哪个类 public @interface IDVlidation { String message() default ""; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) @Retention(RUNTIME) @interface List { IDVlidation[] value(); } }
这样就定义好了一个规则的注解,
使用自定义注解和使用系统的注解一样,添加到需要校验的属性上面即可:
@IDVlidation(message = "省份证不符合规范") private String idCard;
获取校验的后不满足规则的错误信息方式有两种:
一种就像上面一样在 方法参数中检验的对象后面添加 BindingResult result,
@RequestMapping("/book/creat") public String create(@Validated BokBean bokBean, BindingResult result, Model model){
第二种是单独写一个获取错误信息的方法,在方法上添加注解,@ExceptionHandler(BindException.class),
通过 BindException ex 一样能获得第一种方法的BindingResult 对象.对错误信息的进一步操作和第一种方法一样.
@ExceptionHandler(BindException.class) public String resolveBindinngExcrption(BindException ex){ //获取错误结果集. BindingResult result = ex.getBindingResult(); FieldError error = ex.getFieldError(); System.out.println(result); return "erro"; }
分组校验:
某些时候,我们前端的某些请求需要对某个对象的一部分属性进行校验,有一部分属性不需要校验.
这时我们就需要对校验的属性进行分组,根据前端的需求对属性进行分类.
比如登录和注册业务,他们引用的都是用户对象,但是登录只需要校验用户名和密码,而注册除了校验登录和注册还需要校验很多数据,
假如规定了注册时手机号不能为空,在登陆时不需要手机号,就会报错,这时就需要用分组来针对性的校验.
创建一个实体类,并对属性添加校验规则和分组信息,
public class UserBean { //登录分组 public interface LoginGroup{} //注册分组 public interface RegisterGroup{} @NotBlank(message = "不能为空",groups = {LoginGroup.class,RegisterGroup.class}) private String username; @JsonIgnore //表示不想序列化的数据 @NotBlank(groups = {LoginGroup.class,RegisterGroup.class}) private String password; @Pattern(message = "手机号错误",regexp = "1[3-9][\d]{9}",groups = {RegisterGroup.class}) @NotNull(message = "手机号不能为空",groups = {RegisterGroup.class}) private String mobile; @AssertTrue(groups = {RegisterGroup.class}) private boolean agree; @JsonFormat(pattern = "yyyy-MM-dd-HH:mm:ss",timezone = "GMT+8") private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public boolean isAgree() { return agree; } public void setAgree(boolean agree) { this.agree = agree; } }
分组校验用法:
在实体类中创建内部接口类(可以是普通类),用来对业务进行分类,
public class UserBean { //登录分组 public interface LoginGroup{} //注册分组 public interface RegisterGroup{}
在属性的检验规则中添加分组属性 :
@NotBlank(message = "不能为空",groups = {LoginGroup.class,RegisterGroup.class})
表示这个不能为空的检验规则登录和注册都需要满足.
//登录分组 public interface LoginGroup{} //注册分组 public interface RegisterGroup{} @NotBlank(message = "不能为空",groups = {LoginGroup.class,RegisterGroup.class}) private String username; @JsonIgnore //表示不想序列化的数据 @NotBlank(groups = {LoginGroup.class,RegisterGroup.class}) private String password; @Pattern(message = "手机号错误",regexp = "1[3-9][\d]{9}",groups = {RegisterGroup.class}) @NotNull(message = "手机号不能为空",groups = {RegisterGroup.class}) private String mobile; @AssertTrue(message = "必须为真",groups = {RegisterGroup.class}) private boolean agree;
规定好校验规则和分组后,只需在需要校验的地方使用就可以,
用法:在方法参数检验标记中添加分组属性:@Validated(UserBean.LoginGroup.class)
表示只有被UserBean.LoginGroup.class分组的校验规则才会被列入本次校验
@Controller public class UserController { @RequestMapping("/login") public String login(@Validated(UserBean.LoginGroup.class) UserBean userBean){ return "success"; } @RequestMapping("/register") public String register(@Validated(UserBean.RegisterGroup.class) UserBean userBean){ return "success"; }