Close

Spring MVC - Customizing data binding with @InitBinder

[Last Updated: Dec 8, 2017]

What is @InitBinder?

To customize request parameter data binding, we can use @InitBinder annotated methods within our controller.

This customization is not limited to request parameters, it can be applied to template URI variables and backing/command objects.


The signature of @InitBinder method.

The methods annotated with @InitBinder support all arguments types that handler methods supports, except for command/form objects and corresponding validation result objects.

One of the argument should be WebDataBinder.

Return type should be void.

@Controller
public class MyController{
 @InitBinder
 public void customizeBinding (WebDataBinder binder, ......) {
 }
   ....
}


What we can do with WebDataBinder?

WebDataBinder extends DataBinder.

It can be used to register custom formatter, validators and PropertyEditors.

    WebDataBinder.addCustomFormatter(..);
    WebDataBinder.addValidators(..);
    WebDataBinder.registerCustomEditor(..);


When @InitBinder methods get called?

The @InitBinder annotated methods will get called on each HTTP request if we don't specify the 'value' element of this annotation.

Each time this method is called a new instance of WebDataBinder is passed to it.

To be more specific about which objects our InitBinder method applies to, we can supply 'value' element of the annotation @InitBinder. The 'value' element is a single or multiple names of command/form attributes and/or request parameters that this init-binder method is supposed to apply to.

    @InitBinder("user")
    public void customizeBinding (WebDataBinder binder) {...}

We can define multiple @InitBinder methods having different names.



Our Example

We are going to enhance the previous example of User registration. we will demonstrate how to use custom PropertyEditor to setup an implicit conversion of input String to Date.

Also see Spring Core PropertyEditors support.



Create Backing/Command Object

Comparing with our last example we are going to add an additional dateOfBirth field.

  public class User {
    private Long id;

    @Size(min = 5, max = 20)
    private String name;


    @Size(min = 6, max = 15)
    @Pattern(regexp = "\\S+", message = "Spaces are not allowed")
    private String password;

    @NotEmpty
    @Email
    private String emailAddress;

    @NotNull
    private Date dateOfBirth;
    

    //getters and setters
 }



Create Controller with @InitBinder annotated method


@Controller
@RequestMapping("/register")
public class UserRegistrationController {
    @Autowired
    private UserService userService;

    @InitBinder("user")
    public void customizeBinding (WebDataBinder binder) {
        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
        dateFormatter.setLenient(false);
        binder.registerCustomEditor(Date.class, "dateOfBirth",
                                    new CustomDateEditor(dateFormatter, true));
    }

    @RequestMapping(method = RequestMethod.GET)
    public String handleGetRequest (Model model) {
        model.addAttribute("user", new User());
        return "user-registration";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String handlePostRequest (@Valid @ModelAttribute("user") User user,
                                     BindingResult bindingResult, Model model) {
        if (bindingResult.hasErrors()) {
            return "user-registration";
        }

        userService.saveUser(user);
        model.addAttribute("users", userService.getAllUsers());
        return "registration-done";
    }
}


Example Project

To test controllers run the unit tests in RegistrationControllerTest.

Or you can run the app using embedded tomcat:

mvn  clean install tomcat7:run-war

Dependencies and Technologies Used:

  • Spring Web MVC 4.2.4.RELEASE: Spring Web MVC.
  • Spring TestContext Framework 4.2.4.RELEASE: Spring TestContext Framework.
  • Java Servlet API 3.0.1
  • javax.servlet:jstl 1.2
  • Hibernate Validator Engine 5.2.4.Final: Hibernate's Bean Validation (JSR-303) reference implementation.
  • JUnit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
  • JDK 1.8
  • Maven 3.0.4

Spring Custom Property Editor Select All Download
  • spring-custom-property-editor
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • UserRegistrationController.java
          • webapp
            • WEB-INF
              • views
        • test
          • java
            • com
              • logicbig
                • example



    See Also