Java @initbinder不适用于特定的模型属性
我使用@valid和@initbinder对传递给服务的数据进行验证,但我面临的问题是Java @initbinder不适用于特定的模型属性,java,validation,spring-mvc,annotations,Java,Validation,Spring Mvc,Annotations,我使用@valid和@initbinder对传递给服务的数据进行验证,但我面临的问题是@initbinder仅在全局范围内起作用,即 @InitBinder // possible to leave off for global behavior protected void initBinder(WebDataBinder binder){ binder.setValidator(new LoginRequestValidator()); } 而不是针对特定的模型属性,比如我有一个名
@initbinder
仅在全局范围内起作用,即
@InitBinder // possible to leave off for global behavior
protected void initBinder(WebDataBinder binder){
binder.setValidator(new LoginRequestValidator());
}
而不是针对特定的模型属性,比如我有一个名为LoginRequest的模型对象:
@InitBinder("LoginRequest") // possible to leave off for global behavior
protected void initBinder(WebDataBinder binder){
binder.setValidator(new LoginRequestValidator());
}
在这种情况下,根本不会调用验证程序。。这样做对吗?还是我遗漏了什么?查看您的方法的签名,它必须是
@InitBinder("loginRequest")
带有一个小l
@InitBinder
的值可以是以下值之一
- 模型属性的名称
- 请求参数的名称
- 如果上述任何一项都不适用,则可以使用类的名称,但以小写字母开头。这就是Spring向模型公开未命名属性的方式
- @a-better-oliver的答案很好,但下面是另一种解决Spring相同问题的方法,更详细但类型安全:
@InitBinder
protected void initBinder(WebDataBinder binder){
if (binder.getTarget() != null
&& LoginRequest.class.equals(binder.getTarget().getClass())) {
binder.setValidator(new LoginRequestValidator());
}
}
通过这种方式,我们不依赖硬编码字符串,也不关心Spring如何公开未命名的属性。控制器方法的签名是什么样子的?
public@ResponseBody LoginResponse performLogin(@Valid@RequestBody LoginRequest LoginRequest,HttpServletRequest,HttpServletResponse)
我只想知道一件事,我们可以为超过1个验证器提供一个通用的initbinder吗?如果你是这个意思的话,每个模型(或类)可以有一个验证器。因此,通用的init binder方法可以根据模型/类设置验证器。请注意,现代的验证方法是JSR 303 Bean validation,顺便说一句,它消除了手动设置验证器的需要。我有一个由所有其他控制器扩展的基本控制器,因此我考虑在那里放置一个公共@InitBinder,它将调用我定义的所有验证器。。那么想知道这是否可能吗?这是否意味着您为每个对象调用多个验证器,例如为loginRequest
调用两个验证器?这是不可能的。另一方面,如果你有一个用于loginRequest
的验证器,一个用于SomethingElse
的验证器,你可以调用binder.getObjectName()
或binder.getTarget()
,如果它是loginRequest
设置LoginRequestValidator
等等。是的,你可以使用Bean验证。无论您如何发送数据:)