Spring中@Valid和@Validated的区别

Posted

技术标签:

【中文标题】Spring中@Valid和@Validated的区别【英文标题】:Difference between @Valid and @Validated in Spring 【发布时间】:2016-07-10 11:00:01 【问题描述】:

Spring 支持两种不同的验证方法:Spring 验证和 JSR-303 bean 验证。两者都可以通过定义一个委托给其他委托者(包括 bean 验证器)的 Spring 验证器来使用。到目前为止一切顺利。

但是,当注释方法以实际请求验证时,就另当别论了。我可以这样注释

@RequestMapping(value = "/object", method = RequestMethod.POST)
public @ResponseBody TestObject create(@Valid @RequestBody TestObject obj, BindingResult result) 

或者像这样

@RequestMapping(value = "/object", method = RequestMethod.POST)
public @ResponseBody TestObject create(@Validated @RequestBody TestObject obj, BindingResult result) 

这里,@Valid 是 javax.validation.Valid,@Validated 是 org.springframework.validation.annotation.Validated。后者的文档说

JSR-303 Valid 的变体,支持验证规范 团体。专为方便使用 Spring 的 JSR-303 支持而设计,但 不是 JSR-303 特定的。

这并没有多大帮助,因为它并不能准确地说明它有何不同。如果有的话。两者似乎对我来说都很好。

【问题讨论】:

可能会很有趣:***.com/questions/18911154/… “支持验证组的规范”是一个非常明确的说法。 我应该认为 Valid 与 JSR 303 验证(NotNull 等)紧密结合。而您可以创建其他验证/组并将它们签入 Validated。 @zeroflagL,是的,但由于我从未使用过它,所以我错过了重点,而是专注于“非 JSR-303 特定”部分。现在很清楚了。 【参考方案1】:

@Validated 可用于类:

@Validated
public class Person 
    @Size(min=3)
    private String name;
...

【讨论】:

【参考方案2】:

在问题的示例代码 sn-ps 中,@Valid@Validated 没有区别。但是如果@RequestBodyList对象注解,或者是@RequestParam注解的字符串值,则验证不会生效。

我们可以使用@Validated 的方法级验证功能使其工作。要实现这一点,关键是将@Validated 放在类上。这可能是spring框架中@Valid@Validated的另一个重要区别。

参考

Spring boot docs

【讨论】:

您能解释一下为什么注释对List 对象没有影响吗?我认为这也不适用于Map 等其他集合?也许您可以在我的问题中给我更详细的解释:***.com/questions/60167961/… @Theiaz 如你所愿 我在寻找什么! 这实际上是比验证组更重要的区别。没有人使用验证组。【参考方案3】:

除此之外,您只能将@Valid 应用于域/字段以进行嵌套验证,而不能使用@validated

【讨论】:

【参考方案4】:

更直接的答案。 对于那些仍然不知道什么是“验证组”的人。

用于@Valid 验证

控制器:

@RequestMapping(value = "createAccount")
public String stepOne(@Valid Account account) ...

表单对象:

public class Account 

    @NotBlank
    private String username;

    @Email
    @NotBlank
    private String email;



用于@Validated 验证组 来源:http://blog.codeleak.pl/2014/08/validation-groups-in-spring-mvc.html

控制器:

@RequestMapping(value = "stepOne")
public String stepOne(@Validated(Account.ValidationStepOne.class) Account account) ...

@RequestMapping(value = "stepTwo")
public String stepTwo(@Validated(Account.ValidationStepTwo.class) Account account) ...

表单对象:

public class Account 

    @NotBlank(groups = ValidationStepOne.class)
    private String username;

    @Email(groups = ValidationStepOne.class)
    @NotBlank(groups = ValidationStepOne.class)
    private String email;

    @NotBlank(groups = ValidationStepTwo.class)
    @StrongPassword(groups = ValidationStepTwo.class)
    private String password;

    @NotBlank(groups = ValidationStepTwo.class)
    private String confirmedPassword;


【讨论】:

【参考方案5】:

正如您从文档中引用的那样,添加了 @Validated 以支持“验证组”,即经过验证的 bean 中的字段组。这可以在多步骤表单中使用,您可以在第一步中验证姓名、电子邮件等,然后在后续步骤中验证其他字段。

之所以没有将其添加到@Valid注解中是因为它是使用java社区流程(JSR-303)标准化的,这需要时间,而Spring开发人员希望让人们更快地使用此功能。

转到this jira ticket 以查看注释是如何产生的。

【讨论】:

以上是关于Spring中@Valid和@Validated的区别的主要内容,如果未能解决你的问题,请参考以下文章

java注解@Valid@Validated表单验证

SpringBoot @Valid 和 @Validated 的区别及使用方法

@validated 验证 List 参数在spring中

@Validated注解和@Valid注解区别

@Valid 和 @Validated 注解用法详解

@Validated和@Valid校验