# File Upload
# Uploading a single file
To receive a file uploaded via an HTTP Post, you need to do the following:
@RequestMapping(
value = "...",
method = RequestMethod.POST,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
)
public Object uploadFile(
@RequestPart MultipartFile file
) {
String fileName = file.getOriginalFilename();
InputStream inputStream = file.getInputStream();
String contentType = file.getContentType();
.
.
.
}
Note that the name of the @RequestPart
parameter needs to match up with the name of the part in the request.
As HTML:
<form action="/..." enctype="multipart/form-data" method="post">
<input type="file" name="file">
</form>
As HTML (Spring TagLibs (opens new window)):
<form action="/..." enctype="multipart/form-data" method="post">
<form:input type="file" path="file">
</form>
As a raw HTTP request:
POST /... HTTP/1.1
Host: ...
Content-Type: multipart/form-data; boundary=----------287032381131322
------------287032381131322
Content-Disposition: form-data; name="file"; filename="r.gif"
Content-Type: image/gif
GIF87a.............,...........D..;
------------287032381131322--
That request would mean the following:
fileName == "r.gif"
contentType == "image/gif"
In Spring MVC
Need to add the mentioned bean for accessing multipart functionality
<!-- max size of file in memory (in bytes) -->
<property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
</bean>
# Marshaling a part into an object
If you want to convert the content of a part into a domain object (e.g. a User
or Account
or Address
), then the process is very simple:
It is possible to upload multiple parts, each with a different name. For each part name, you will need one parameter annotated with @RequestPart
, whose name matches the part name.
To receive a file uploaded via an HTTP Post, you need to do the following:
@RequestMapping(
value = "...",
method = RequestMethod.POST,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
)
public Object uploadFile(
@RequestPart Address address,
) {
.
.
.
}
As a raw HTTP request:
POST /... HTTP/1.1
Host: ...
Content-Type: multipart/form-data; boundary=----------287032381131322
------------287032381131322
Content-Disposition: form-data; name="address"; filename="address.json"
Content-Type: application/json
{"houseNumber": "10/A", "streetName": "Dumbldore Road", "town": "Hogsmede"}
------------287032381131322--
The most important things are:
- The name of the part must match the name of the variable.
- The
Content-Type
of the part must be one that Spring would be able to handle if you had sent it as a regular request. That is, if you could perform aPOST
to an endpoint with aContent-Type
offoo/bar
, and Spring is able to turn that into an object, then it will also be able to marshal a part into an object. - You must be able to set the
Content-Type
of the part. If you cannot, this approach will not work - Spring will not attempt to guess theContent-Type
of the part.
# Uploading multiple files
To receive multiple files uploaded via a single HTTP Post, you need to do the following:
@RequestMapping(
value = "...",
method = RequestMethod.POST,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
)
public Object uploadFile(
@RequestPart MultipartFile[] files
) {
for (file : files) {
String fileName = file.getOriginalFilename();
InputStream inputStream = file.getInputStream();
String contentType = file.getContentType();
.
.
.
}
}
Note that the name of the @RequestPart
parameter needs to match up with the name of the part in the request.
As HTML:
<form action="/..." enctype="multipart/form-data" method="post">
<input type="file" name="files">
<input type="file" name="files">
</form>
As a raw HTTP request:
POST /... HTTP/1.1
Host: ...
Content-Type: multipart/form-data; boundary=----------287032381131322
------------287032381131322
Content-Disposition: form-data; name="files"; filename="r.gif"
Content-Type: image/gif
GIF87a.............,...........D..;
------------287032381131322
Content-Disposition: form-data; name="files"; filename="banana.jpeg"
Content-Type: image/jpeg
GIF87a.............,...........D..;
------------287032381131322--
That request would mean the following:
files[0].getOriginalFilename() == "r.gif"
files[0].getContentType() == "image/gif"
files[1].getOriginalFilename() == "r.jpeg"
files[1].getContentType() == "image/jpeg"
# Uploading multiple parts with different names
It is possible to upload multiple parts, each with a different name. For each part name, you will need one parameter annotated with @RequestPart
, whose name matches the part name.
To receive a file uploaded via an HTTP Post, you need to do the following:
@RequestMapping(
value = "...",
method = RequestMethod.POST,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
)
public Object uploadFile(
@RequestPart MultipartFile profilePicture,
@RequestPart MultipartFile companyLogo,
) {
.
.
.
}
As HTML:
<form action="/..." enctype="multipart/form-data" method="post">
<input type="file" name="profilePicture">
<input type="file" name="companyLogo">
</form>
As a raw HTTP request:
POST /... HTTP/1.1
Host: ...
Content-Type: multipart/form-data; boundary=----------287032381131322
------------287032381131322
Content-Disposition: form-data; name="profilePicture"; filename="r.gif"
Content-Type: image/gif
GIF87a.............,...........D..;
------------287032381131322
Content-Disposition: form-data; name="companyLogo"; filename="banana.jpeg"
Content-Type: image/jpeg
GIF87a.............,...........D..;
------------287032381131322--
# Syntax
# Parameters
Parameter | Details |
---|---|
@RequestPart (opens new window) | This annotation specifies that a parameter should be mapped to a given request part. The part name must match the name of the method parameter, unless you choose to provide it as an argument to @RequestPart . If the part name is not expressible as a Java name (e.g. 123 ), then you can use the value attribute of the @RequestPart to specify the actual name. e.g. @RequestPart("123") String _123 . |
# Remarks
If you are running on an older version of Java (pre 1.7), or are compiling without debug information, then Java will replace the name of the parameter with arg0
, arg1
, etc, which will prevent Spring from being able to match them up with the part names. If that is the case, then you will need to set the name of the part in the @RequestPart
annotation, as documented in Parameters.