更新
This commit is contained in:
		
							
								
								
									
										177
									
								
								java/Jsr303校验.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								java/Jsr303校验.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
# JSR303数据校验
 | 
			
		||||
 | 
			
		||||
	JSR303是Java为Bean数据合法性校验提供给的标准框架,已经包含在 JavaEE6.0 中、JSR303通过在Bean 属性中标注类似 @NotNull @Max 等标准的注解指定校验规则并通过标准的验证接口对 Bean进行验证
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###  注解
 | 
			
		||||
 | 
			
		||||
### JSR303中含有的注解
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
	    @Null   被注释的元素必须为 null  
 | 
			
		||||
	    @NotNull    被注释的元素必须不为 null  
 | 
			
		||||
	    @AssertTrue     被注释的元素必须为 true  
 | 
			
		||||
	    @AssertFalse    被注释的元素必须为 false  
 | 
			
		||||
	    @Min(value)     被注释的元素必须是一个数字,其值必须大于等于指定的最小值  
 | 
			
		||||
	    @Max(value)     被注释的元素必须是一个数字,其值必须小于等于指定的最大值  
 | 
			
		||||
	    @DecimalMin(value)  被注释的元素必须是一个数字,其值必须大于等于指定的最小值  
 | 
			
		||||
	    @DecimalMax(value)  被注释的元素必须是一个数字,其值必须小于等于指定的最大值  
 | 
			
		||||
	    @Size(max=, min=)   被注释的元素的大小必须在指定的范围内  
 | 
			
		||||
	    @Digits (integer, fraction)     被注释的元素必须是一个数字,其值必须在可接受的范围内  
 | 
			
		||||
	    @Past   被注释的元素必须是一个过去的日期  
 | 
			
		||||
	    @Future     被注释的元素必须是一个将来的日期  
 | 
			
		||||
	    @Pattern(regex=,flag=)  被注释的元素必须符合指定的正则表达式  
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Hibernate Validator 附加的注解
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
	    @NotBlank(message =)   验证字符串非null,且长度必须大于0  
 | 
			
		||||
	    @Email  被注释的元素必须是电子邮箱地址  
 | 
			
		||||
	    @Length(min=,max=)  被注释的字符串的大小必须在指定的范围内  
 | 
			
		||||
	    @NotEmpty   被注释的字符串的必须非空  
 | 
			
		||||
	    @Range(min=,max=,message=)  被注释的元素必须在合适的范围内
 | 
			
		||||
	
 | 
			
		||||
	    注:HIbernate Validator是JSR303的一个参考实现,除了支持所有标准的校验注解外,另外HIbernate Validator还有JSR-380的实现  
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### SpringMVC中使用JSR303进行服务器端验证
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
		a. 添加相关依赖
 | 
			
		||||
		      <dependency>
 | 
			
		||||
		            <groupId>org.hibernate</groupId>
 | 
			
		||||
		            <artifactId>hibernate-validator</artifactId>
 | 
			
		||||
		            <version>6.0.7.Final</version>
 | 
			
		||||
		      </dependency>
 | 
			
		||||
		b.  给校验对象的指定属性添加校验规则
 | 
			
		||||
		      public class User {
 | 
			
		||||
			private Long userId;
 | 
			
		||||
		
 | 
			
		||||
			@NotBlank(message = "用户名不能为空")
 | 
			
		||||
			private String userName;
 | 
			
		||||
		
 | 
			
		||||
			@NotBlank(message = "密码不能为空")
 | 
			
		||||
			private String userPwd;
 | 
			
		||||
		
 | 
			
		||||
		        ............
 | 
			
		||||
		 
 | 
			
		||||
		       }
 | 
			
		||||
		c. 在请求处理方法中,使用@Validated或@Valid注解要验证的对象,并根据BindingResult判断校验是否通过 另外,验证参数后必须紧跟BindingResult参数,否则spring会在校验不通过时直接抛出异常
 | 
			
		||||
		
 | 
			
		||||
		  public String login(@Validated @ModelAttribute User user,
 | 
			
		||||
			BindingResult bindingResult){
 | 
			
		||||
	    // 服务器端校验不通过
 | 
			
		||||
	if (bindingResult.hasErrors()) {
 | 
			
		||||
		return "login";
 | 
			
		||||
	}            
 | 
			
		||||
	    ....
 | 
			
		||||
	  }
 | 
			
		||||
	
 | 
			
		||||
	 注1:@Valid和Validated的区别,随便使用哪个都行
 | 
			
		||||
	 @Valid是使用hibernate validation的时候使用
 | 
			
		||||
	 @Validated 是只用spring  Validator校验机制使用
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###   在JSP页面上通过form标签显示消息
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
          <form:errors path="*" /> 显示表单所有错误
 | 
			
		||||
          <form:errors path="user* /> 显示所有以user为前缀的属性对应的错误
 | 
			
		||||
          <form:errors path="username"/> 显示特定表单对象属性的错误
 | 
			
		||||
          
 | 
			
		||||
          delimiter:如果一个属性有多个错误,错误信息的分隔符。默认是换行
 | 
			
		||||
     注1:errors标签要放到form标签中才能显示错误消息
 | 
			
		||||
     注2:如果使用form:errors标签不显示错误消息,请检查Model中是否已经添加了命令对象,没有是不会显示错误消息的
 | 
			
		||||
     注3:注意命名规范,Book-->book  
 | 
			
		||||
    @ModelAttribute
 | 
			
		||||
     public void init(Model model) {
 | 
			
		||||
        System.out.println("init...");
 | 
			
		||||
        model.addAttribute("user", new User());
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
###   通过BindingResult和form:errors标签在JSP页面显示非验证消息
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public String login(@Valid @ModelAttribute Yh yh, BindingResult bindingResult, Model model){
 | 
			
		||||
            bindingResult.rejectValue("yhzh", null, "帐号错误");
 | 
			
		||||
            ...
 | 
			
		||||
          }
 | 
			
		||||
      bindingResult.rejectValue("email", "validate.email.empty", "邮箱不能为空");//这个函数有好几个重载的变体
 | 
			
		||||
      它们是可以支持国际化的。 比如,上面这个例子表示, 错误的字段(filed)是“email”, errorCode是“validate.email.empty”, 与资源文件对应, 第三个是defaultMessage
 | 
			
		||||
     
 | 
			
		||||
      作业1:从BindingResult对象获得错误消息,生成基于json字符串返回到客户端
 | 
			
		||||
 | 
			
		||||
如何实现分组校验
 | 
			
		||||
2.1 通过接口定义若干个分组
 | 
			
		||||
  2.2 给校验对象的指定属性添加校验规则,并指定校验组
 | 
			
		||||
  2.3 在请求处理方法中,使用@Validated标记要验证的对象,并指定校验组
 | 
			
		||||
 | 
			
		||||
还可以对验证进行分组(@Validated)
 | 
			
		||||
public class Book {
 | 
			
		||||
	// 书本验证分组
 | 
			
		||||
	public static interface ValidateGroups {
 | 
			
		||||
		// 新增/修改
 | 
			
		||||
		public static interface AddEdit {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
// 上架/下架
 | 
			
		||||
public static interface DeployUndeploy {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 更新封面
 | 
			
		||||
public static interface UpdateBookImage {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private Long bookId;
 | 
			
		||||
 | 
			
		||||
@NotBlank(message = "书名不能为空", groups = { AddEdit.class })
 | 
			
		||||
private String bookName;
 | 
			
		||||
 | 
			
		||||
private String bookNamePinyin;
 | 
			
		||||
 | 
			
		||||
@NotNull(message = "类别不能为空", groups = { AddEdit.class })
 | 
			
		||||
private Long bookCategoryId;
 | 
			
		||||
 | 
			
		||||
@NotBlank(message = "作者不能为空", groups = { AddEdit.class })
 | 
			
		||||
private String bookAuthor;
 | 
			
		||||
 | 
			
		||||
@NotNull(message = "价格不能为空", groups = { AddEdit.class })
 | 
			
		||||
@Min(value = 1, message = "价格不能为负")
 | 
			
		||||
private Double bookPrice;
 | 
			
		||||
 | 
			
		||||
private Long bookImage;
 | 
			
		||||
 | 
			
		||||
@NotBlank(message = "出版社不能为空", groups = { AddEdit.class })
 | 
			
		||||
private String publishing;
 | 
			
		||||
 | 
			
		||||
@NotBlank(message = "简介不能为空", groups = { AddEdit.class })
 | 
			
		||||
private String bookDesc;
 | 
			
		||||
 | 
			
		||||
private Integer bookState;
 | 
			
		||||
 | 
			
		||||
private Date deployDatetime;
 | 
			
		||||
 | 
			
		||||
private Integer salesVolume;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@RequestMapping("/add")
 | 
			
		||||
	public String add(
 | 
			
		||||
			@Validated(value = Book.BookGroups.Add.class) @ModelAttribute Book book,
 | 
			
		||||
			BindingResult bindingResult) {
 | 
			
		||||
		if (bindingResult.hasErrors()) {
 | 
			
		||||
			return "admin/addBook";
 | 
			
		||||
		}
 | 
			
		||||
		return "admin/addBook";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
3. 通过分组来指定顺序
 | 
			
		||||
   @GroupSequence({First.class, Second.class, User.class}) 
 | 
			
		||||
		Reference in New Issue
	
	Block a user