http://evgeny-goldin.com/blog/uploading-files-multipart-post-apache/
I had to implement a files transferring mechanism where one machine was sending files to another using "multipart/form-data" POST request. It can be done using Apache’s Commons FileUpload andHttpClient.
The receiving part was an easy one:
|
1
2
3
4
5
|
<
dependency
>
<
groupid
>commons-fileupload</
groupid
>
<
artifactid
>commons-fileupload</
artifactid
>
<
version
>1.2.1</
version
>
</
dependency
>
|
We parse an incoming request with ServletFileUpload and get a list of FileItems in return. EachFileItem is either form’s input field or a file uploaded:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
if
( ServletFileUpload.isMultipartContent( request ))
{
List<fileitem> fileItems =
new
ServletFileUpload(
new
DiskFileItemFactory(
1024
*
1024
, DIR )).
parseRequest( request );
for
( FileItem item : fileItems )
{
String fieldName = item.getFieldName();
if
( item.isFormField()) { item.getString() }
// Form's input field
else
{ item.getInputStream() }
// File uploaded
}
}
|
In our case, we use DiskFileItemFactory to store files larger than 1Mb in a temporary DIR. After reading file’s InputStream and storing the data in a proper storage – we need to delete the temporary copy:item.delete().
It’s the sending part that came out to be a bit trickier. Initially, I was using a simple HTML form:
|
1
2
3
4
5
|
<
input
type
=
"file"
name
=
"file"
>
<
input
type
=
"text"
name
=
"paramName"
>
<
input
type
=
"submit"
name
=
"Submit"
value
=
"Upload File"
>
</
form
>
|
But then I’ve switched back to Java and assumed HttpClient will do the job.
|
1
2
3
4
5
|
<
dependency
>
<
groupid
>org.apache.httpcomponents</
groupid
>
<
artifactid
>httpclient</
artifactid
>
<
version
>4.0.1</
version
>
</
dependency
>
|
Eventually, it did but it took me some time to figure out how. The problem with HttpClient is that it provides a nice tutorial and various usage examples but none of them actually mentions a word about uploading files!
I’ve figured out I need to set an instance of HttpEntity to request but it seemed like it’s going to be either a StringEntity or FileEntity but not both. How come ?! Why is it so hard to send a usual POST request with String and file parameters?
Ok, it’s Google time.
Some examples and documentation were referring to an outdated version when HttpClient was part of Apache Commons and, therefore, were of no use for me – the API has changed dramatically. Until I’ve found this example that finally saved my day. Radomir, thank you!
The solution is to use an additional Apache component – HttpMime:
|
1
2
3
4
5
6
7
8
9
10
11
|
<
dependency
>
<
groupid
>org.apache.httpcomponents</
groupid
>
<
artifactid
>httpclient</
artifactid
>
<
version
>4.0.1</
version
>
</
dependency
>
<
dependency
>
<
groupid
>org.apache.httpcomponents</
groupid
>
<
artifactid
>httpmime</
artifactid
>
<
version
>4.0.1</
version
>
</
dependency
>
|
and then we finally get to use a magical MultipartEntity:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
HttpClient client =
new
DefaultHttpClient();
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost post =
new
HttpPost( url );
MultipartEntity entity =
new
MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
// For File parameters
entity.addPart( paramName,
new
FileBody((( File ) paramValue ),
"application/zip"
));
// For usual String parameters
entity.addPart( paramName,
new
StringBody( paramValue.toString(),
"text/plain"
,
Charset.forName(
"UTF-8"
)));
post.setEntity( entity );
// Here we go!
String response = EntityUtils.toString( client.execute( post ).getEntity(),
"UTF-8"
);
client.getConnectionManager().shutdown();
|
Note the use of EntityUtils for reading the response.
That’s it.
I only wish library authors were providing better support and examples for more common cases like files uploading in our case. I mean, come on, when people get to use HttpClient they either want to send a usual request or upload a file, same thing they do with browser. Am I wrong here?
本文详细介绍了如何使用Apache HttpClient库实现文件上传功能,包括引入依赖、解析multipart/form-data格式请求、处理文件和字符串参数等关键步骤。通过实例演示了发送包含文件和普通字符串参数的POST请求的方法。


被折叠的 条评论
为什么被折叠?



