使用带注释的MVC控制器中的以下验证设置:
@RestController
@RequestMapping("/users")
@Validated // <-- without this, the @Size annotation in setPassword() has no effect
public class UserController {
@PutMapping("/{id}/password")
public void setPassword(@PathVariable long id, @RequestBody @Size(min = 8) String password) {
/* ... */
}
@PutMapping("/{id}/other")
public void setOther(@PathVariable long id, @RequestBody @Valid MyFormObject form) {
/* ... */
}
}
方法参数需要在控制器上的@Valid
,因为它不是一个“复杂”对象。相比之下,set其他
方法上的@Valid
注解在没有@Valed
注解的情况下也可以工作。
为什么需要@验证
?为什么不默认启用它?使用它有成本吗?
请注意,在Spring中@Valid和@Val的区别是相关的(我在问这个问题之前阅读了它),但它并没有解决我问题中的原因。
对象的验证由Hibernate Validator使用Jakarta Bean Validation2.0的注释完成。需要一些东西来触发hibernate validator才能运行。
SpringMVC在看到带有@Valid
的参数时调用控制器方法,它会将该对象传递给Hibernate验证器。Hibernate验证器将
所以在这种情况下
@PutMapping("/{id}/other")
public void setOther(@PathVariable long id, @RequestBody @Valid MyFormObject form) {
/* ... */
}
MyFormObject
上面有注释,Hibernate验证器可以找到这些注释来验证对象。
在这种情况下
@PutMapping("/{id}/password")
public void setPassword(@PathVariable long id, @RequestBody @Size(min = 8) String password) {
/* ... */
}
java. lang.String上没有定义任何注释供Hibernate验证器发现。
@Valid
来自Bean验证包javax. valid.Valid
,而@Valided
来自Springorg.springframe.validation.annotation.Valided
@验证
注解激活Spring验证AOP拦截器,它将检查方法参数以查看它们是否有任何验证注解,如果它们有,那么Spring将使用每个特定的注解调用hibernate验证器,例如@Size(min=8)字符串密码
意味着调用hibernate大小验证器并传递参数密码的值,在这种情况下,hibernate验证器不需要扫描java. lang.String
以查看它是否有验证注解。@验证
适用于任何Spring@Component
,例如您可以在@Service
类上使用它。
与使用@Transactional
类似,使用@Valid
会有额外的开销,因此您必须选择使用它。在javax. valid.Valid的情况下,SpringMVC需要检查控制器方法参数的注释,因此当它看到@Valid
时,它很容易将该对象发送到Hibernate Validator,而无需添加AOP拦截器。