提交 f4b7cfea 编写于 作者: R Rossen Stoyanchev

SPR-8483 Update reference documentation with multipart request-related...

SPR-8483 Update reference documentation with multipart request-related changes: @RequestPart, Servlet 3.0 multipart reuqests, javax.servlet.http.Part method argument types.
上级 75ad1855
...@@ -1112,9 +1112,8 @@ public class RelativePathUriTemplateController { ...@@ -1112,9 +1112,8 @@ public class RelativePathUriTemplateController {
<listitem> <listitem>
<para><interfacename>@RequestPart</interfacename> annotated parameters <para><interfacename>@RequestPart</interfacename> annotated parameters
for access to the content of a "multipart/form-data" request part. for access to the content of a "multipart/form-data" request part.
Parameter values are converted to the declared method argument type using See <xref linkend="mvc-multipart-forms-non-browsers" /> and
<interfacename>HttpMessageConverter</interfacename>s. See <xref <xref linkend="mvc-multipart"/>.</para>
linkend="mvc-ann-requestpart" />.</para>
</listitem> </listitem>
<listitem> <listitem>
...@@ -1415,67 +1414,6 @@ public void handle(@RequestBody String body, Writer writer) throws IOException { ...@@ -1415,67 +1414,6 @@ public void handle(@RequestBody String body, Writer writer) throws IOException {
</note> </note>
</section> </section>
<section id="mvc-ann-requestpart">
<title>Mapping the content of a part of a "multipart/form-data" request with the
<interfacename>@RequestPart</interfacename> annotation</title>
<para>A "multipart/form-data" request contains a series of parts each with its own
headers and content. It is commonly used for handling file uploads on a form --
see <xref linkend="mvc-multipart"/> -- but can also be used to send or receive
a request with multiple types of content.</para>
<para>The <interfacename>@RequestPart</interfacename> annotation works very similarly to the
<interfacename>@RequestBody</interfacename> annotation except instead of looking in the
body of the HTTP request, it binds the method parameter to the content of one of the
parts of a "multipart/form-data" request. Here is an exampe:</para>
<programlisting language="java">
@RequestMapping(value="/configurations", method = RequestMethod.POST)
public String onSubmit(<emphasis role="bold">@RequestPart("meta-data") MetaData metadata</emphasis>) {
<lineannotation>// ...</lineannotation>
}
</programlisting>
<para>The actual request may look like this:</para>
<programlisting language="xml">
POST /configurations
Content-Type: multipart/mixed
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="meta-data"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
{
"name": "value"
}
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="file-data"; filename="file.properties"
Content-Type: text/xml
Content-Transfer-Encoding: 8bit
... File Data ...
</programlisting>
<para>In the above example, the <literal>metadata</literal> argument is bound to the content
of the first part of the request called <literal>"meta-data"</literal> containing JSON content.
In this case we specified the name of the request part in the
<interfacename>@RequestPart</interfacename> annotation but we might have been able to leave it
out if the name of the method argument matched the request part name.</para>
<para>Just like with <interfacename>@RequestBody</interfacename> you convert the content of
the request part to the method argument type by using an
<classname>HttpMessageConverter</classname>. Also you can add <literal>@Valid</literal>
to the method argument to have the resulting object automatically validated.
If validation fails a <classname>RequestPartNotValidException</classname> is raised.
The exception is handled by the <classname>DefaultHandlerExceptionResolver</classname> and
results in a <literal>400</literal> error sent back to the client along with a message
containing the validation errors.</para>
</section>
<section id="mvc-ann-responsebody"> <section id="mvc-ann-responsebody">
<title>Mapping the response body with the <interfacename>@ResponseBody</interfacename> <title>Mapping the response body with the <interfacename>@ResponseBody</interfacename>
annotation</title> annotation</title>
...@@ -3037,9 +2975,10 @@ background=/themes/cool/img/coolBg.jpg</programlisting> ...@@ -3037,9 +2975,10 @@ background=/themes/cool/img/coolBg.jpg</programlisting>
applications. You enable this multipart support with pluggable applications. You enable this multipart support with pluggable
<interfacename>MultipartResolver</interfacename> objects, defined in the <interfacename>MultipartResolver</interfacename> objects, defined in the
<literal>org.springframework.web.multipart</literal> package. Spring <literal>org.springframework.web.multipart</literal> package. Spring
provides a <interfacename>MultipartResolver</interfacename> for use with provides one <interfacename>MultipartResolver</interfacename> implementation
<ulink url="http://jakarta.apache.org/commons/fileupload"> for use with <ulink url="http://jakarta.apache.org/commons/fileupload">
<emphasis>Commons FileUpload</emphasis></ulink>).</para> <emphasis>Commons FileUpload</emphasis></ulink> and another for use
with Servlet 3.0 multipart request parsing.</para>
<para>By default, Spring does no multipart handling, because some <para>By default, Spring does no multipart handling, because some
developers want to handle multiparts themselves. You enable Spring developers want to handle multiparts themselves. You enable Spring
...@@ -3052,9 +2991,9 @@ background=/themes/cool/img/coolBg.jpg</programlisting> ...@@ -3052,9 +2991,9 @@ background=/themes/cool/img/coolBg.jpg</programlisting>
treated like any other attribute.</para> treated like any other attribute.</para>
</section> </section>
<section id="mvc-multipart-resolver"> <section id="mvc-multipart-resolver-commons">
<title>Using the <title>Using a <interfacename>MultipartResolver</interfacename>
<interfacename>MultipartResolver</interfacename></title> with <emphasis>Commons FileUpload</emphasis></title>
<para>The following example shows how to use the <para>The following example shows how to use the
<classname>CommonsMultipartResolver</classname>:</para> <classname>CommonsMultipartResolver</classname>:</para>
...@@ -3082,6 +3021,33 @@ background=/themes/cool/img/coolBg.jpg</programlisting> ...@@ -3082,6 +3021,33 @@ background=/themes/cool/img/coolBg.jpg</programlisting>
get access to the multipart files themselves in your controllers.</para> get access to the multipart files themselves in your controllers.</para>
</section> </section>
<section id="mvc-multipart-resolver-standard">
<title>Using a <interfacename>MultipartResolver</interfacename>
with <emphasis>Servlet 3.0</emphasis></title>
<para>In order to use Servlet 3.0 based multipart parsing,
you need to mark the <classname>DispatcherServlet</classname> with a
<literal>"multipart-config"</literal> section in
<filename>web.xml</filename>, or with a
<classname>javax.servlet.MultipartConfigElement</classname> in
programmatic servlet registration, or in case of a custom servlet class
possibly with a <classname>javax.servlet.annotation.MultipartConfig</classname>
annotation on your servlet class. Configuration settings such as
maximum sizes or storage locations need to be applied at that
servlet registration level as Servlet 3.0 does not allow for
those settings to be done from the MultipartResolver.</para>
<para>Once Servlet 3.0 multipart parsing has been enabled
in one of the above mentioned ways you can add the
<classname>StandardServletMultipartResolver</classname>
to your Spring configuration:</para>
<programlisting language="xml">&lt;bean id="multipartResolver"
class="org.springframework.web.multipart.support.StandardServletMultipartResolver"&gt;
&lt;/bean&gt;</programlisting>
</section>
<section id="mvc-multipart-forms"> <section id="mvc-multipart-forms">
<title>Handling a file upload in a form</title> <title>Handling a file upload in a form</title>
...@@ -3115,7 +3081,7 @@ background=/themes/cool/img/coolBg.jpg</programlisting> ...@@ -3115,7 +3081,7 @@ background=/themes/cool/img/coolBg.jpg</programlisting>
public class FileUpoadController { public class FileUpoadController {
@RequestMapping(value = "/form", method = RequestMethod.POST) @RequestMapping(value = "/form", method = RequestMethod.POST)
public String handleFormUpload(@RequestParam("name") String name, public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) { @RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) { if (!file.isEmpty()) {
...@@ -3134,18 +3100,92 @@ public class FileUpoadController { ...@@ -3134,18 +3100,92 @@ public class FileUpoadController {
example, nothing is done with the <literal>byte[]</literal>, but in example, nothing is done with the <literal>byte[]</literal>, but in
practice you can save it in a database, store it on the file system, and practice you can save it in a database, store it on the file system, and
so on.</para> so on.</para>
<para>When using Servlet 3.0 multipart parsing you can also use
<classname>javax.servlet.http.Part</classname> for the method parameter:
<programlisting language="java">@Controller
public class FileUpoadController {
<para>Finally, you will have to declare the controller and the resolver @RequestMapping(value = "/form", method = RequestMethod.POST)
in the application context:</para> public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") Part file) {
<programlisting language="xml">&lt;beans&gt; InputStream inputStream = file.getInputStream();
&lt;bean id="multipartResolver" <lineannotation>// store bytes from uploaded file somewhere</lineannotation>
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/&gt;
<lineannotation>&lt;!-- Declare explicitly, or use &lt;context:annotation-config/&gt; --&gt;</lineannotation> return "redirect:uploadSuccess";
&lt;bean id="fileUploadController" class="examples.FileUploadController"/&gt; }
}</programlisting></para>
</section>
<section id="mvc-multipart-forms-non-browsers">
<title>Handling a file upload request from programmatic clients</title>
<para>Multipart requests can also be submitted from non-browser clients in
a RESTful service scenario. All of the above examples and configuration
apply here as well. However, unlike browsers that typically submit files
and simple form fields, a programmatic client can also send more complex
data of a specific content type -- for exmaple a multipart request with
a file and second part with JSON formatted data:
<programlisting language="xml">
POST /someUrl
Content-Type: multipart/mixed
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="meta-data"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
{
"name": "value"
}
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="file-data"; filename="file.properties"
Content-Type: text/xml
Content-Transfer-Encoding: 8bit
... File Data ...
</programlisting></para>
<para>You could access the part named "meta-data" with
<interfacename>@RequestParam("meta-data") String metadata</interfacename>
controller method argument. However, you would probably
prefer to accept a strongly typed object initialized
from the JSON formatted data in the body of the request
part, very similar to the way
<interfacename>@RequestBody</interfacename> converts
the body of a non-multipart requests to a target object
with the help of an <classname>HttpMessageConverter</classname>.</para>
<para>You can use the <interfacename>@RequestPart</interfacename>
annotation instead of the <interfacename>@RequestParam</interfacename>
annotation for this purpose. It allows you to have the
content of a specific multipart passed through an
<classname>HttpMessageConverter</classname>
taking into consideration the <literal>'Content-Type'</literal>
header of the multipart:
<programlisting language="java">
@RequestMapping(value="/someUrl", method = RequestMethod.POST)
public String onSubmit(<emphasis role="bold">@RequestPart("meta-data") MetaData metadata,
@RequestPart("file-data") MultipartFile file,</emphasis>) {
<lineannotation>// ...</lineannotation>
}
</programlisting></para>
<para>Notice how you <classname>MultipartFile</classname>
method arguments can be accessed with <interfacename>@RequestParam</interfacename>
or with <interfacename>@RequestPart</interfacename> interchangeably.
However, the <literal>@RequestPart("meta-data") MetaData</literal>
method argument in this case is read as JSON content
based on its <literal>'Content-Type'</literal>
header and converted with help of the
<classname>MappingJacksonHttpMessageConverter</classname>.
</para>
&lt;/beans&gt;</programlisting>
</section> </section>
</section> </section>
<section id="mvc-exceptionhandlers"> <section id="mvc-exceptionhandlers">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册