SPR-8483 Update reference documentation with multipart request-related changes: @RequestPart, Servlet 3.0 multipart reuqests, javax.servlet.http.Part method argument types.
This commit is contained in:
parent
75ad185558
commit
f4b7cfea38
|
|
@ -1112,9 +1112,8 @@ public class RelativePathUriTemplateController {
|
|||
<listitem>
|
||||
<para><interfacename>@RequestPart</interfacename> annotated parameters
|
||||
for access to the content of a "multipart/form-data" request part.
|
||||
Parameter values are converted to the declared method argument type using
|
||||
<interfacename>HttpMessageConverter</interfacename>s. See <xref
|
||||
linkend="mvc-ann-requestpart" />.</para>
|
||||
See <xref linkend="mvc-multipart-forms-non-browsers" /> and
|
||||
<xref linkend="mvc-multipart"/>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
|
@ -1415,67 +1414,6 @@ public void handle(@RequestBody String body, Writer writer) throws IOException {
|
|||
</note>
|
||||
</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">
|
||||
<title>Mapping the response body with the <interfacename>@ResponseBody</interfacename>
|
||||
annotation</title>
|
||||
|
|
@ -3037,9 +2975,10 @@ background=/themes/cool/img/coolBg.jpg</programlisting>
|
|||
applications. You enable this multipart support with pluggable
|
||||
<interfacename>MultipartResolver</interfacename> objects, defined in the
|
||||
<literal>org.springframework.web.multipart</literal> package. Spring
|
||||
provides a <interfacename>MultipartResolver</interfacename> for use with
|
||||
<ulink url="http://jakarta.apache.org/commons/fileupload">
|
||||
<emphasis>Commons FileUpload</emphasis></ulink>).</para>
|
||||
provides one <interfacename>MultipartResolver</interfacename> implementation
|
||||
for use with <ulink url="http://jakarta.apache.org/commons/fileupload">
|
||||
<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
|
||||
developers want to handle multiparts themselves. You enable Spring
|
||||
|
|
@ -3052,9 +2991,9 @@ background=/themes/cool/img/coolBg.jpg</programlisting>
|
|||
treated like any other attribute.</para>
|
||||
</section>
|
||||
|
||||
<section id="mvc-multipart-resolver">
|
||||
<title>Using the
|
||||
<interfacename>MultipartResolver</interfacename></title>
|
||||
<section id="mvc-multipart-resolver-commons">
|
||||
<title>Using a <interfacename>MultipartResolver</interfacename>
|
||||
with <emphasis>Commons FileUpload</emphasis></title>
|
||||
|
||||
<para>The following example shows how to use the
|
||||
<classname>CommonsMultipartResolver</classname>:</para>
|
||||
|
|
@ -3082,6 +3021,33 @@ background=/themes/cool/img/coolBg.jpg</programlisting>
|
|||
get access to the multipart files themselves in your controllers.</para>
|
||||
</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"><bean id="multipartResolver"
|
||||
class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
|
||||
</bean></programlisting>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="mvc-multipart-forms">
|
||||
<title>Handling a file upload in a form</title>
|
||||
|
||||
|
|
@ -3115,7 +3081,7 @@ background=/themes/cool/img/coolBg.jpg</programlisting>
|
|||
public class FileUpoadController {
|
||||
|
||||
@RequestMapping(value = "/form", method = RequestMethod.POST)
|
||||
public String handleFormUpload(@RequestParam("name") String name,
|
||||
public String handleFormUpload(@RequestParam("name") String name,
|
||||
@RequestParam("file") MultipartFile file) {
|
||||
|
||||
if (!file.isEmpty()) {
|
||||
|
|
@ -3134,18 +3100,92 @@ public class FileUpoadController {
|
|||
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
|
||||
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
|
||||
in the application context:</para>
|
||||
@RequestMapping(value = "/form", method = RequestMethod.POST)
|
||||
public String handleFormUpload(@RequestParam("name") String name,
|
||||
@RequestParam("file") Part file) {
|
||||
|
||||
<programlisting language="xml"><beans>
|
||||
<bean id="multipartResolver"
|
||||
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
|
||||
<lineannotation><!-- Declare explicitly, or use <context:annotation-config/> --></lineannotation>
|
||||
<bean id="fileUploadController" class="examples.FileUploadController"/>
|
||||
InputStream inputStream = file.getInputStream();
|
||||
<lineannotation>// store bytes from uploaded file somewhere</lineannotation>
|
||||
|
||||
return "redirect:uploadSuccess";
|
||||
}
|
||||
|
||||
}</programlisting></para>
|
||||
|
||||
</beans></programlisting>
|
||||
</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>
|
||||
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="mvc-exceptionhandlers">
|
||||
|
|
|
|||
Loading…
Reference in New Issue