JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。
1 校验注解
1.1 @Null
校验属性必须为null,适合id自增这种字段,需要在新增数据时为null。
1.2 @NotNull
不能为null,添加数字时常用,例:Integer,Long,Double。
1.3 @NotBlank
至少有一个字符且不能为空格,添加String类型参数时常用。
1.4 @NotEmpty
不能为空或null,适用于对象,集合,数组。
1.5 @URL
必须是符合规范的url。
1.6 @Pattern
自定义校验规则,可以使用正则表达式校验 ,例:@Pattern(regexp = “正则规则” , groups = {AddGroup.class, UpdateGroup.class})
1.7 各注解中参数说明
message:校验不通过的提示信息。
groups:校验所属组,搭配@Validated注解一起使用时,可以给校验注解添加分组,当校验注解与@Validated注解中分组匹配时,校验才生效。
2 使校验注解生效的注解
2.1 @Vaild
告诉SpringMVC开启校验,只加@NotBlank不加@Vaild,那么@NotBlank无效。
2.2 @Validated
设置分组,根据分组(接口)类型进行校验,比如只在进行添加操作时校验或者进行修改操作时校验,添加@Validated注解如果不在校验注解(@NotBlank、@NotNull…)上设置分组,那么校验注解无效。
3 举个栗子
3.1测试工具类
1. 测试controller
@RestController
@RequestMapping("test")
public class TestController {
@GetMapping("test1")
public void test1( @Validated({AddGroup.class}) TestDto dto) {
System.out.println(123);
}
@GetMapping("test2")
public void test2( @Validated({AddGroup.class}) @Valid TestDto dto) {
System.out.println(123);
}
@GetMapping("test3")
public void test3(@Valid TestDto dto) {
System.out.println(123);
}
@GetMapping("test4")
public void test4( TestDto dto) {
System.out.println(123);
}
}
2. 测试分组接口AddGroup
public interface AddGroup {
}
3. 测试Dto类
@Data
public class TestDto {
@NotBlank(message = "test01不为空")
private String test01;
@NotBlank(message = "test02不为空",groups = {AddGroup.class})
private String test02;
@NotBlank(message = "test03不为空")
private Long test03;
@NotEmpty(message = "test04不为空")
private List<String> test04;
}
3.2 栗子
3.2.1 接收参数前没加@Vaild或者@Validated
如果只是在TestDto中属性加上了校验注解,但是TestController中接口方法在接收参数处没有加@Valid或者@Validated注解,TestDto中校验注解加了相当于没加,例如TestController中的test4方法。
//无效
@GetMapping("test4")
public void test4( TestDto dto) {
System.out.println(123);
}
3.2.2 注意各个校验注解的使用场景
例如其中的@NotBlank只能校验字符串类型的属性,如果加在其他类型上,校验时或报错的,如果没报错,那就得检查校验注解是否失效了。
//校验时报错
@NotBlank(message = "test03不为空")
private Long test03;
错误样子:
HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type 'java.lang.Long'. Check configuration for 'test03'
3.2.3 一般的使用场景
一般常用的使用就是接收参数Dto类中加上校验注解,然后接口方法在Dto前面加上生效注解@Vaild即可。
像这样:
//Dto
@Data
public class TestDto {
@NotBlank(message = "test01不为空")
private String test01;
@NotBlank(message = "test02不为空",groups = {AddGroup.class})
private String test02;
@NotBlank(message = "test03不为空")
private Long test03;
@NotEmpty(message = "test04不为空")
private List<String> test04;
}
//controller
@GetMapping("test3")
public void test3(@Valid TestDto dto) {
System.out.println(123);
}
3.2.4 分组校验的使用
使用分组校验,可以实现不同的业务场景运用不同的校验规则。例如,在新增一条数据时,其id属性必须为空(id一般后端生成,保证自增),而在新增时id不为空,这种场景下,如果想用注解校验来实现的话,就需要在id属性上加上@Null和@NotNull这两个自相矛盾的注解,这里可以采用分组校验来实现。
例如:
//Dto中
@Null(message = " id须为空",groups={AddGroup.class})
@NotNull(message = " id不能为空",groups={UptateGroup.class})
private Long id;
//controller中
@GetMapping("add")
public void add( @Validated({AddGroup.class}) TestDto dto) {
//新增
}
@GetMapping("update")
public void update( @Validated({UptateGroup.class}) TestDto dto) {
//修改
}
像上面这样就可以实现不同业务场景下使不同校验注解生效,其中的AddGroup和UptateGroup可以是自定义的两个接口,一个校验注解可以有多个分组。
需要注意的是,此时如果@Validated个@Valid一起使用会怎样?答案是只有@Validated注解会生效,也就是说此时只有分了组的校验注解才生效,别指望没有加分组校验的属性能通过@Valid来生效。
3.3 使用总结
总的来说,校验注解有两种,一种是分了类的(加了groups参数的),一种是没有分类的,就是@Validated用于生效分了组的校验注解,@Valid用于生效没有分组的校验注解,各管各的,且同一时间只有一种会生效。如果想要一个属性分没分组都生效,可以一个注解加两次,像这样:
@NotBlank(message = "test02不为空",groups = {AddGroup.class})
@NotBlank(message = "test02不为空")
private String test02;
需要注意的是,如果同时使用了@Validated和@Valid会怎样?分了组的和没分组的校验注解会都生效吗?答案是不会的,只有加在靠前面的那个会生效。
标签:JSR303,校验,关于,注解,message,Validated,class,NotBlank From: https://www.cnblogs.com/wjx001/p/17573732.html