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

时间:2014-08-05 16:28:47

标签: java spring forms 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>

从代码中我很想到只有输入类型=&#34;文件&#34;是以新的方式发送的。休息全部作为键值对发送。我认为这本书也是一样的&#34; 当提交表单时,它将被发布为多部分表单,其中一个部分包含图像文件的二进制数据。&#34 ;

Q2&gt; 如果我的想法是正确的,客户如何知道哪些输入类型作为键值对发送以及单独发送给谁?

1 个答案:

答案 0 :(得分:1)

首先,multipart / form-data的enctype 不是一个Spring-MVC的东西,它是一般web开发中<form>的一个属性,这意味着这个属性可以是无论服务器端技术如何,都存在于HTML表单中。您可以在此处详细了解相关信息:HTML 5 Candidate Recommendation [Specification] 4 The elements of HTML 4.10 Forms 4.10.22 Form submission 4.10.22.7 Multipart form data,您还可以通过阅读RFC2388详细了解数据的发送方式。如果您查看它,您将看到在POST请求中使用multipart / form-data发送的数据不再是键/值对,而是包含多个部分(是的,它是多部分),其中每个部分看起来像这样(示例属于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 Specification中找到另一个示例,其中显示了上传两个或多个文件时更具体的示例(我的评论在<--之后发布):

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