Why the @InitBinder method is called for every request?

9.1k views Asked by At

While I was debugging my Spring Boot application I noticed that methods annotated with @InitBinder are invoked for every incoming request.

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

In @InitBinder methods we are setting a PropertyEditor to a binder. I can't understand why should these methods be called again and again and set the same thing?
Does Spring create a new WebDataBinder object for every single request?

2

There are 2 answers

0
Kaypro II On

It looks like this was answered in a post by Rossen Stoyanchev in the now defunct Spring Forums: https://web.archive.org/web/20181223143621if_/http://forum.spring.io/forum/spring-projects/web/55552-why-does-initbinder-method-get-called-multiple-times:

A WebDataBinder instance is specific to a model attribute. You can verify the target model attribute a data binder is created for like this:

Code:

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

Data binders are also used for @RequestParam's and by default an init-binder method is used for for all model attribute and request parameters.

Given the number of request parameters and model attributes you have, what you most likely want to do is be more specific about which objects your InitBinder method applies to. For example:

Code:

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

There was also this follow-up question:

Does it mean that we may specify for which command object the binder will be applied? Let's say if we have multi-action controller which deals with 2 different domain object User which is represented by "user" and Report "report" then: @InitBinder("user") annotated method will be called only when binding the User object and the @InitBinder("report") only when binding Report?

Yes, it means that's the model attribute or request parameter to which this specific data binding customization will apply. You can also provide an array of names.

1
Kunal On

@InitBinder plays the role to identify the methods which used to initialize WebDataBinder. Initbinder is usually used to bind requestParams to custom objects.

Suppose your REST controller is annotated with @InitBinder, every request is handled within that controller will instantiate Initbinder and WebDatabinderwill bind the request params to JavaBean objects.

It provides methods to assign our validator classes. Using addValidators() and setValidator() methods, we can assign our validators instances.

Use Case: Suppose Sun, Jan 20 is in the request param and you want to have a LocalDate Object parsed everytime from request parm. You can add that parser logic within WebDatabinder and have that date validated/parsed everytime the request is made.

Reference: What is the purpose of init binder in spring MVC