想去放牛

导航

 
 

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会怎样?分了组的和没分组的校验注解会都生效吗?答案是不会的,只有加在靠前面的那个会生效。@Validated是@Valid注解的封装,如果没有进行分组校验的情况下,@Validated可以代替@Valid注解,如果加了分组限制,@Validated就只会进行分组校验。

posted on 2023-07-22 17:10  想去放牛  阅读(228)  评论(0编辑  收藏  举报