@initbinder 不适用于特定的模型属性

Posted

技术标签:

【中文标题】@initbinder 不适用于特定的模型属性【英文标题】:@initbinder not working for specific model attribute 【发布时间】:2013-06-24 20:37:57 【问题描述】:

我正在使用@valid 和@initbinder 来验证传递给服务的数据,但我面临@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());

在这种情况下,根本没有调用验证器。这是正确的方法吗?还是我错过了什么?

【问题讨论】:

你的控制器方法的签名是什么样子的? public @ResponseBody LoginResponse performLogin(@Valid @RequestBody LoginRequest loginRequest, HttpServletRequest request, HttpServletResponse response) 【参考方案1】:

@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 如何暴露未命名的属性。

【讨论】:

【参考方案2】:

查看你的方法的签名,它必须是

@InitBinder("loginRequest")

带有小号

@InitBinder 的值可以是以下之一

模型属性的名称 请求参数的名称 如果以上都不适用,则可以使用类的名称,但以小写字母开头。这就是 Spring 向模型公开未命名属性的方式。

【讨论】:

只是想知道一件事,我们可以为超过 1 个验证器提供一个通用的 initbinder 吗? 你可以为每个模型(或类)拥有一个验证器,如果你是这个意思的话。因此,一个常见的 init binder 方法可以根据模型/类设置验证器。请注意,现代验证方法是 JSR 303 Bean 验证,顺便说一句,它消除了手动设置验证器的需要。 我有一个由所有其他控制器扩展的基本控制器,所以我想在那里放置一个通用的@InitBinder 它将调用我定义的所有验证器..所以想知道这是否可能? 这是否意味着您为每个对象调用多个验证器,例如loginRequest 的两个验证器?这不是直接可能的。另一方面,如果您有一个验证器用于loginRequest,一个用于SomethingElse,您可以调用binder.getObjectName()binder.getTarget(),如果它是loginRequest,则设置LoginRequestValidator 等。跨度> 是的,您可以使用 Bean 验证。您如何发送数据并不重要:)

以上是关于@initbinder 不适用于特定的模型属性的主要内容,如果未能解决你的问题,请参考以下文章

百里香叶。 th:each 不适用于模型属性

Ember 数据模型中的计算属性不适用于 ember-cli-mirage 模型

在我的模型中,flask-restless 不适用于混合属性

springMVC-InitBinder

客户端验证不适用于重用和嵌套的复杂属性

内容安全策略 nonce 不适用于事件处理程序属性