了解enctype = multipart/form-data在spring mvc中的工作



在我读过的《Spring In Action》一书中,帖子提交的默认内容类型是application/x-www-form-urlencoded,并采用与号分隔的名称-值对的形式。(我相信这些都是HTTP POST请求的主体有效负载)

我进一步阅读,与enctype设置为multipart/form-data,每个字段将作为POST请求的不同部分提交,而不仅仅是作为另一个名称-值对。

Q1> 我不明白这条线。我来自REST背景,想了解HTTP POST请求的内容发生了什么变化?

服务器端代码

@RequestMapping(method=RequestMethod.POST)
public String addSpitterFromForm(@Valid Spitter spitter,
    BindingResult bindingResult,
    @RequestParam(value="image", required=false)
Accept file upload
      MultipartFile image) {
if(bindingResult.hasErrors()) {
  return "spitters/edit";
}
spitterService.saveSpitter(spitter);
try {
  if(!image.isEmpty()) {
    validateImage(image);
Validate image
      saveImage(spitter.getId() + ".jpg", image); //
    }
  } catch (ImageUploadException e) {
    bindingResult.reject(e.getMessage());
    return "spitters/edit";
}
  return "redirect:/spitters/" + spitter.getUsername();
}
客户端代码
    <sf:form method="POST"
                     modelAttribute="spitter"
                     enctype="multipart/form-data">
//other stuff
     <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><label for="image">Profile image:</label></th>
      <td><input name="image" type="file"/>
    </tr>
//other stuff
    </sf:form>

从代码中,我很想认为只有输入type="file"以新的方式发送。其余的都以键值对的形式发送。我认为这本书也在说同样的"当表单提交时,它将作为一个多部分表单发布,其中一个部分包含图像文件的二进制数据。 "

Q2>如果我想的是正确的,客户端如何知道哪些输入类型作为键值对发送和谁单独发送?

首先,multipart/form-data的enctype 不是Spring-MVC的东西,它是一般web开发中<form>的属性,这意味着无论服务器端技术如何,该属性都可以出现在HTML表单中。你可以在这里阅读更多:HTML 5候选推荐[规范]4 HTML 4.10表单的元素4.10.22表单提交4.10.22.7多部分表单数据,也可以通过阅读RFC2388来具体了解数据将如何发送。如果你回顾一下,你会发现在POST请求中发送的数据与多部分/表单数据不再是键/值对,而是包含多个部分(是的,它是多部分),每个部分看起来像这样(示例属于RFC2388):

--AaB03x
content-disposition: form-data; name="field1"
content-type: text/plain;charset=windows-1250
content-transfer-encoding: quoted-printable
Joe owes =80100.
--AaB03x

注意Joe owes =80100.是指Joe owes €100

你可以在HTML 4规范中找到另一个例子,它在上传两个或更多文件时显示了一个更具体的例子(我的评论在<--之后发布):

Content-Type: multipart/form-data; boundary=AaB03x <-- mark for the whole request
--AaB03x <-- content of a part
Content-Disposition: form-data; name="submit-name" <-- field name
Larry <-- content of the field
--AaB03x <-- content of a part
Content-Disposition: form-data; name="files"
Content-Type: multipart/mixed; boundary=BbC04y
--BbC04y <-- content of a part containing a file
Content-Disposition: file; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--BbC04y <-- content of a part containing a file
Content-Disposition: file; filename="file2.gif"
Content-Type: image/gif
Content-Transfer-Encoding: binary
...contents of file2.gif...
--BbC04y-- <-- end of parts containing file
--AaB03x-- <-- end of whole request data

最新更新