【问题标题】:Why the @InitBinder method is called for every request?为什么每个请求都调用@InitBinder 方法?
【发布时间】:2019-01-05 05:30:06
【问题描述】:

在调试 Spring Boot 应用程序时,我注意到每个传入请求都会调用带有 @InitBinder 注释的方法。

@InitBinder("categories")
public void bindFields(WebDataBinder binder) {
    binder.registerCustomEditor(Set.class, new CustomPropertyEditor());
}

@InitBinder 方法中,我们将PropertyEditor 设置为活页夹。我不明白为什么要一次又一次地调用这些方法并设置相同的东西?
Spring 是否为每个请求创建一个新的 WebDataBinder 对象?

【问题讨论】:

  • 实际上在spring 5中,一个GET请求(一个POST请求相同)和带有@initBinder注解的方法被调用了3次!这是怎么回事???
  • 啊,#3 这里其实是我的问题的答案forum.spring.io/forum/spring-projects/web/…
  • 太棒了...论坛已经死了。
  • 这是该论坛帖子的存档链接:web.archive.org/web/20181223143621if_/http://forum.spring.io/…。看起来这就是答案:“WebDataBinder 实例特定于模型属性。您可以像这样验证为数据绑定器创建的目标模型属性......鉴于您拥有的请求参数和模型属性的数量,什么您最可能想要做的是更具体地了解您的 InitBinder 方法适用于哪些对象。”

标签: java spring spring-boot data-binding spring-mvc-initbinders


【解决方案1】:

@InitBinder 的作用是识别用于初始化WebDataBinder 的方法。 Initbinder 通常用于将 requestParams 绑定到自定义对象。

假设您的 REST 控制器带有 @InitBinder 注释,在该控制器中处理的每个请求都会实例化 Initbinder,WebDatabinder 会将请求参数绑定到 JavaBean 对象。

它提供了分配我们的验证器类的方法。使用addValidators()setValidator() 方法,我们可以分配我们的验证器实例。

用例:假设 Sun,1 月 20 日在请求参数中,并且您希望每次都从请求参数中解析一个 LocalDate 对象。您可以在 WebDatabinder 中添加该解析器逻辑,并在每次发出请求时验证/解析该日期。

参考:What is the purpose of init binder in spring MVC

【讨论】:

  • 但是为什么感觉每次都要调用方法呢?
【解决方案2】:

Rossen Stoyanchev 在now defunct Spring 论坛:https://web.archive.org/web/20181223143621if_/http://forum.spring.io/forum/spring-projects/web/55552-why-does-initbinder-method-get-called-multiple-times

WebDataBinder 实例特定于模型属性。你可以 验证创建数据绑定器的目标模型属性 这个:

代码:

@InitBinder
public void initBinder(WebDataBinder binder) {
    System.out.println("A binder for object: " + binder.getObjectName());
}

数据绑定器也用于@RequestParam,默认情况下是 init-binder 方法用于所有模型属性和请求 参数。

鉴于您拥有的请求参数和模型属性的数量, 您最可能想要做的是更具体地说明哪个 您的 InitBinder 方法适用的对象。例如:

代码:

@InitBinder("tasks")
public void initBinder(WebDataBinder binder) {
    System.out.println("A binder for object: " + binder.getObjectName());
}

还有这个后续问题:

这是否意味着我们可以指定绑定器将应用于哪个命令对象?假设我们有一个多动作控制器,它处理 2 个不同的域对象用户,由“用户”和报告“报告”表示,那么:@InitBinder(“用户”)注解的方法只会在绑定用户对象时被调用,并且@InitBinder("report") 只在绑定Report的时候?

是的,这意味着该特定数据绑定自定义将应用到的模型属性或请求参数。您还可以提供名称数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-13
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多