使用 springboot 2.4.0,OpenJDK 11
背景
在使用 SpringBoot 实现 Controller 的 Request InDto 时,需要校验参数的取值、格式等
所以使用到 spring-boot-starter-validation
来实现校验。然后发现有 @Valid
和 @Validated
两个 annotation。
以下介绍它们之间的区别和用法。
@Valid
所在 package
javax.validation
定义
Marks a property, method parameter or method return type for validation cascading.
Constraints defined on the object and its properties are be validated when the property, method parameter or method return type is validated.
This behavior is applied recursively.
它标记一个属性、方法参数或方法返回值需要级联地验证,这意味着每当使用它标记一个参数时,这个参数里面的各个属性都被验证。
例子
Controller(@Valid
)
@RestController
public class MembershipController{
@PostMapping("/create-membership-remark")
public MembershipRemarkOutDto createMembershipRemark(
@RequestBody @Valid CreateMembershipRemarkInDto aCreateMembershipRemarkInDto) {
return membershipFacade.createMembershipRemark(aCreateMembershipRemarkInDto);
}
}
CreateMembershipRemarkInDto(不检查 CreateBarInDto bar
)
public class CreateMembershipRemarkInDto {
@NotBlank
private String remark;
@NotBlank
private String fooStr;
@NotNull // 此处不加 @Valid 则不会检查 CreateBarInDto
private CreateBarInDto bar;
public static class CreateBarInDto {
@NotBlank
private String barStr;
}
}
解释
在参数中使用 @Valid
意味着 参数中的各个属性都会被校验(如 remark
, useless
和 bar
)
但是 bar
只会被校验它本身 @NotNull, 不会校验它的属性是否满足要求
CreateMembershipRemarkInDto(检查 CreateBarInDto bar
)
如果需要检查 CreateBarInDto
,则需要改为如下的形式:
public class CreateMembershipRemarkInDto {
@NotBlank
private String remark;
@NotBlank
private String fooStr;
@NotNull
@Valid // 增加 @Valid 注解
private CreateBarInDto bar;
public static class CreateBarInDto {
@NotBlank
private String barStr;
}
}
解释
此时 bar
也会被校验它的属性(如 barStr
)是否满足要求
@Validated
所在 package
org.springframework.validation.annotation
定义
@Validated
是 @Valid
的变体(variant)。
通过声明 InDto 中属性的 groups
,再搭配使用 @Validated
,就能决定哪些属性需要校验,哪些不需要校验
例子
Controller(@Validated
)
@RestController
public class MembershipController{
@PostMapping("/create-membership-remark")
public MembershipRemarkOutDto createMembershipRemark(
@RequestBody @Validated({Useful.class}) CreateMembershipRemarkInDto aCreateMembershipRemarkInDto) {
return membershipFacade.createMembershipRemark(aCreateMembershipRemarkInDto);
}
}
CreateMembershipRemark
public class CreateMembershipRemarkInDto {
@NotBlank(groups = Useful.class)
private String remark;
@NotBlank(groups = Useless.class)
private String fooStr;
@NotNull(groups = Useless.class)
@Valid
private CreateBarInDto bar;
@Getter
public static class CreateBarInDto {
@NotBlank
private String barStr;
}
}
Useful interface & Useless interface
public interface Useful {
}
public interface Useless {
}
声明两个空的interface:Useful
和 Useless
,便于区分。
此时就只有声明为 Useful
的会被校验,而 Useless
则不会被校验。
参考文章
Differences in @Valid and @Validated Annotations in Spring
Deep understanding of the role of data validation @Valid (cascade validation)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。