Given some controller that processes input based on a class Contact
with several fields:
@PostMapping(value="")
public String addContactMessage(@Valid @ModelAttribute("contact") Contact contact, Model model) {
// this will print the name provided in the input, without me explicitly saying contact.setName(name)
System.out.println(contact.getName();
return "index.html";
}
... assuming that my Contact class has a private String name
attribute, with a getter and a setter, and I also have an addContact.html
page with a text field
of name="name"
, when I try to print contact.getName()
on screen, Spring Boot returns the name of the contact I entered via the textfield.
That's good, in my opinion, but my question is: why? I didn't even mention a @RequestParam()
inside the controller's parameters and I didn't even instantiate the contact
reference, in order to later assign the user input.
Tried googling about it, but found nothing, to be honest. Could it be from the Validation plugin? My Contact
class has several annotations added, too, including Lombok's the @Data
annotation, but removing them all and manually writing getters and setters would still result in this "auto-mapping". Removing the getters and setters will stop this process from happening.
Also, it seems that the input names should be the same (ignoring case sensitivity) with the class field names (for example, for a field called message
, I should have an input with name="message"
).
My question is, is this a Spring thing? Why does this happen? What happens if I have, for example, three method parameters of type Contact
? Will it map user input to all three of them?
CodePudding user response:
Yes. It is done by the Spring 's Databinder stuff which you can find more info about it at here.
Basically it try to get the values from the HTTP request 's query parameters and the submitted form data , and set it to the model 's properties by calling the corresponding public setter following the JavaBeans naming conventions. For example , for the query parameter which the name is foo
, it will look for the setter setFoo(String val)
in the model to set the value to it.
For the codes about how does it work , you can refer to this as the starting point.
If the controller method has 3 parameters of the type Contact
, both of them will have the same value bounded to them but they are different instances.