1

我正在阅读 Spring in action,现在我正在阅读有关构建 Web 应用程序的章节,但我无法完全掌握一件事

例如,如果我们有这样的方法:

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

这里我们将类的实例添加Spitter到模型中,所以它被传递给这个表单

<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>

用户输入数据后,这些输入数据将绑定到某个Spitter对象并由

    @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();
}  

我将一些对象传递给将要填充的模型,但我很感兴趣这在幕后是如何工作的,因为当页面提供给用户时,有关对象的信息会丢失(或者我错了)?

1.添加的对象是否与请求的数据来时Spring动态创建的第二个对象createSpitterProfile相同(相同的含义引用) ?SpitteraddSpitterFromForm

2.当用户输入进来的请求中addSpitterFromForm,Spring如何知道表单中的信息应该被处理到Spitter对象,我知道Spitter方法签名中有对象,但是Spring如何知道数据应填充此对象属性。

4

1 回答 1

2

您必须记住,客户端 Web 浏览器从服务器获取“普通的旧 HTML”(那里没有魔法/隐藏的 Java)。因此 Spring 将模型对象“编码”为 HTML,以<form>输入、单选、选择等形式。

用户获得一个普通的 HTML 网页,填写表单并按下提交以 POST 或 GET 页面返回到 Web 服务器。这就是 Spring 将请求参数“反编码”回正在绑定的对象(即)的神奇之处Spitter。所以回答 Q1,不,它不是同一个对象,它是一个副本(甚至可能是一个有损副本)。

至于 Q2,当您要求 Spring 将请求绑定到对象时,它所做的只是尝试将请求参数名称与对象上的 setter 匹配。它“知道”是因为您在方法签名中要求它。Spring 在决定如何处理方法签名方面做了一些花哨的事情,并且值得一读,因为你输入参数的顺序很重要。

于 2012-08-24T01:27:24.163 回答