R
R
r3b3l2017-03-30 06:49:57
Spring
r3b3l, 2017-03-30 06:49:57

Spring MVC work with form?

Good afternoon!
It's no secret to anyone who has worked with Spring MVC that Spring has its own tag library. One of these tags will be my question. Namely, about the "form: form" tag, or rather about its modelAttribute attribute (analogous to the obsolete commandName).
Reading the documentation, at first I thought that this attribute is only used to fill the form with some initial data (ie, the basis for the form, backing object). And only for this, for nothing more.
But in the course of work, it turned out that this attribute also determines the object that will be sent by this form and will be received in the controller. But how does it happen? For what? Whereby? Through what mechanism? After all, as far as I know, HTML requests cannot pass objects - they can pass query parameters, but not objects.
If the question is not clear, then I will describe the details. If you understand, then you can not read further.
Just in case, the controller code:

@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView main() {
  User user = new User();
  return new ModelAndView("index", "userObj", user);
}
 
@RequestMapping(value = "/check-user", method = RequestMethod.POST)
public String checkUser(@Valid @ModelAttribute(name = "userObj") User user, BindingResult bindingResult, Model model) {
  if (bindingResult.hasErrors()) return "index";
  return "check-user";
}

And this is the form code:
<form:form class="box login" modelAttribute="userObj" method="POST" action="check-user">
    <fieldset class="boxBody">
        <label>Username</label>
  	<form:input path="name"/>
  	<form:errors path="name" cssClass="error" />
  	<label>Password</label>
  	<form:password path="password"/>
  	<form:errors path="password" cssClass="error"/>
  </fieldset>		
  <footer>
    <form:checkbox path="admin" />
    <label>Admin?</label>
    <input type="submit" class="btnLogin" value="Login" tabindex="4">
  </footer>
</form:form>

Way of thinking:
When requesting "/" the userObj object is placed in the model attribute (which is almost equivalent to adding a request attribute in a non-Spring MVC application, i.e. the userObj model attribute will be available only within a single request) and the index view is given - on it form is located.
The server returns the page with the form. Because useObj is empty, the form will render with empty field values. The request ends, the userObj model attribute is no longer available. Fill in the form fields with values ​​and click submit. A new request starts. The data goes to the checkUser() handler.
In the checkUser() signature:
public String checkUser(@Valid @ModelAttribute(name = "userObj") User user, BindingResult bindingResult, Model model)
you can see that we are extracting the userObj attribute from the model and placing it in the User user variable. But how? After all, this is another request, and the previous userObj attribute (which was empty) has already been lost!
It remains only to assume that the form somehow generates a new model attribute, in which it places the filled user object. But how does it happen technically? After all, as I already wrote, the client's request cannot transfer the model attribute (it can only transfer request parameters - the data entered into the form fields). And this generation occurs, apparently, due to the modelAttribute attribute (obsolete commandName).
It turns out that the server already has information from somewhere that the attribute should be exactly "userObj". If you try to get an attribute with a different name in the controller, for example, "useObj2", then an exception will be thrown. How is information about the model attribute and its name transmitted from the client to the server? How does modelAttribute (deprecated commandName) from a form JSP pass the attribute to the model? Maybe due to the id of the form (into which the Spring form will eventually be rendered and the modelAttribute will become apparently an id)? Or how?
The fact remains that you can get the entered data in the controller only by specifying the value of modelAttribute (obsolete commandName). In the body of the POST request sent from the client, there is information about the entered data, but not and cannot be about the model attribute.
Sincerely, I hope I wrote clearly.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question