1

I am reading Spring in action, and now I am at the chapter about building web application, but I can't fully grasp one thing

If for example we have method like this:

@RequestMapping(method=RequestMethod.GET, params="new")
public String createSpitterProfile(Model model) {
  model.addAttribute(new Spitter());
  return "spitters/edit";
}

here we are adding instance of the Spitter class to the model, so it is passed to this form

<div>
<h2>Create a free Spitter account</h2>

<sf:form method="POST" modelAttribute="spitter" 
    enctype="multipart/form-data">         
  <fieldset> 
  <table cellspacing="0">
  <tr>
    <th><sf:label path="fullName">Full name:</sf:label></th>
    <td><sf:input path="fullName" size="15" /><br/>
    <sf:errors path="fullName" cssClass="error" />
    </td>
  </tr>
  <tr>
    <th><sf:label path="username">Username:</sf:label></th>
    <td><sf:input path="username" size="15" maxlength="15" />
      <small id="username_msg">No spaces, please.</small><br/>
    <sf:errors path="username" cssClass="error" />

    </td>
  </tr>
  <tr>
    <th><sf:label path="password">Password:</sf:label></th>
    <td><sf:password path="password" size="30" 
            showPassword="true"/> 
    <small>6 characters or more (be tricky!)</small><br/>
    <sf:errors path="password" cssClass="error" />
    </td>
  </tr>

  <tr>
    <th><sf:label path="email">Email Address:</sf:label></th>

    <td><sf:input path="email" size="30"/> 
    <small>In case you forget something</small><br/>
    <sf:errors path="email" cssClass="error" />
    </td>
  </tr>
  <!--<start id="image_field"/>--> 
  <tr>
    <th><label for="image">Profile image:</label></th>
    <td><input name="image" type="file"/>
  </tr>
  <!--<end id="image_field"/>--> 
  <tr>
    <th></th>
    <td>
    <sf:checkbox path="updateByEmail"/>
    <sf:label path="updateByEmail" 
    >Send me email updates!</sf:label>

    </td>
  </tr>
  <tr>
    <th></th>
    <td><input name="commit" type="submit" 
        value="I accept. Create my account." /></td>
  </tr>
  </table>
</fieldset>
</sf:form>
</div>

after user inputs his data, those input data will be binded to some Spitter object and will be processed by

    @RequestMapping(method=RequestMethod.POST)
public String addSpitterFromForm(@Valid Spitter spitter, 
BindingResult bindingResult,
@RequestParam(value="image", required=false) MultipartFile image) {

  if(bindingResult.hasErrors()) {
return "spitters/edit";
  } 

  spitterService.saveSpitter(spitter);

  try {
if(!image.isEmpty()) {
  validateImage(image);
  saveImage(spitter.getId() + ".jpg", image);
}
  } catch (ImageUploadException e) {
bindingResult.reject(e.getMessage());
return "spitters/edit";
  }

  return "redirect:/spitters/" + spitter.getUsername();
}  

I passed some object to the model that will be populated, but I am interested how does this work a bit under the hood, because when the page is served to the user, the information about the object is lost (or I am wrong)?

1.Does the object that is added in createSpitterProfile is the same (same meaning reference) as the Spitter object in the addSpitterFromForm or is the second one created by the Spring on the fly when the requested with data comes?

2.When the user input is coming in the request to the addSpitterFromForm, how does Spring know that the information from the form should be processed to the Spitter object, I know that there is Spitter object in the method signature, but how does Spring know that the data should populate this object properties.

1 Answer 1

2

You have to keep in mind that the client web browser gets "plain old HTML" from the server (there is no magic/hidden Java in there). So Spring "encodes" the model object into HTML, in the form of <form> inputs, radio, selects, etc.

The user gets a normal HTML web page, fills in the form and presses submit to POST or GET the page back to the web server. This is where Spring does its magic to "un-encode" the request parameters back into the object that is being binded (i.e. Spitter). So to answer Q1, no its not the same Object, its a copy (and may even be a lossy copy).

As for Q2, when you ask Spring to bind a request to an object, all it is doing is try to match the request parameter names to setters on your object. It "knows" because you asked it to in the method signature. Spring does some fancy stuff in deciding how to deal with method signatures and its worth reading up on it, as the order in which you put arguments does matter.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.