简体   繁体   中英

Apache Http Client 4 Form Post Multi-part data

I need to post some form parameters to a server through an HTTP request (one of which is a file). So I use Apache HTTP Client like so...

HttpPost httpPost = new HttpPost(urlStr);

params = []
params.add(new BasicNameValuePair("username", "bond"));
params.add(new BasicNameValuePair("password", "vesper"));
params.add(new BasicNameValuePair("file", payload));

httpPost.setEntity(new UrlEncodedFormEntity(params));
httpPost.setHeader("Content-type", "multipart/form-data");

CloseableHttpResponse response = httpclient.execute(httpPost);

The server returns an error, stack trace is..

the request was rejected because no multipart boundary was found
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:954)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:156)

I understand from other posts that I need to somehow come up with a boundary, which is a string not found in the content. But how do I create this boundary in the code I have above? Should it be another parameter? Just a code sample is what I need.

As the exception says, you have not specified the "multipart boundary". This is a string that acts as a separator between the different parts in the request. But in you case it seems like you do not handle any different parts.

What you probably want to use is MultipartEntityBuilder so you don't have to worry about how it all works under the hood.

It should be Ok to do the following

        HttpPost httpPost = new HttpPost(urlStr);

        File payload = new File("/Users/CasinoRoyaleBank");

        HttpEntity entity = MultipartEntityBuilder.create()
                .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                .addBinaryBody("file", payload)
                .addTextBody("username", "bond")
                .addTextBody("password", "vesper")
                .build();
        httpPost.setEntity(entity);

However, here is a version that should be compatible with @AbuMariam findings below but without the use of deprecated methods/constructors.

        File payload = new File("/Users/CasinoRoyaleBank");

        ContentType plainAsciiContentType = ContentType.create("text/plain", Consts.ASCII);
        HttpEntity entity = MultipartEntityBuilder.create()
                .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                .addPart("file", new FileBody(payload))
                .addPart("username", new StringBody("bond", plainAsciiContentType))
                .addPart("password", new StringBody("vesper", plainAsciiContentType))
                .build();
        httpPost.setEntity(entity);

        CloseableHttpResponse response = httpclient.execute(httpPost);

The UrlEncodedFormEntity is normally not used for multipart, and it defaults to content-type application/x-www-form-urlencoded

I accepted gustf's answer because it got rid of the exception I was having and so I thought I was on the right track, but it was not complete. The below is what I did to finally get it to work...

File payload = new File("/Users/CasinoRoyaleBank")
MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
entity.addPart( "file", new FileBody(payload))
entity.addPart( "username", new StringBody("bond"))
entity.addPart( "password", new StringBody("vesper"))
httpPost.setEntity( entity );
CloseableHttpResponse response = httpclient.execute(httpPost);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM