0

I am trying to create a multipart post to a URL with the following body:

Content-Disposition: form-data; name="json"
Content-Type: "application/json; charset=UTF-8"

{"input1":"data1","input2":"data2","input3":"data3"}

--APIMultipartPost
Content-Disposition: form-data; name="filePath"; filename="myFile.dat"
Content-Length: 381645
Content-Type: text/plain
Content-Transfer-Encoding: binary

<!-- SNIP -->
<!-- The OWL file was included here in plain text (without the SNIPs) -->
<!-- SNIP -->

I tried using MultipartEntityBuilder to create the multipart post, but probably I do something wrong with the parameters. Can someone help me with the java code for this post?

Here is my code:

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost uploadFile = new HttpPost(URL);

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("input1", "data1");
builder.addTextBody("input2", "data2");
builder.addTextBody("input3", "data3");

builder.addBinaryBody("file", new File("C:/myFile.dat"), ContentType.APPLICATION_OCTET_STREAM, "myFile.dat");
HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
HttpResponse response = httpClient.execute(uploadFile);

and the error I get:

HttpResponseProxy{HTTP/1.1 422 Unprocessable Entity [Server: nginx/1.6.0, Date: Wed, 28 Jan 2015 19:29:42 GMT, Content-Type: application/json;charset=utf-8, Content-Length: 89, Connection: keep-alive, Status: 422 Unprocessable Entity, X-Rack-Cache: invalidate, pass, X-Content-Type-Options: nosniff] ResponseEntityProxy{[Content-Type: application/json;charset=utf-8,Content-Length: 89,Chunked: false]}}

Thank you!

3
  • You did not say what does NOT work and in what way? Any error messages? Any exceptions? Commented Jan 28, 2015 at 16:22
  • I added the response in the initial question. Thanks! Commented Jan 28, 2015 at 17:33
  • It looks like the URL that you are using does NOT expect/can not process the message that it receives. Are you using correct URL? Can it process multi-part requests with json/text AND binary parts? Commented Jan 28, 2015 at 17:56

2 Answers 2

1

The response 422 Unprocessable Entity says

The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.

so as you can see the request you send doesn't fit with the specification of the controller/service that you POST to. If you use a tool like TCPMon you can actually intercept the request that you send and check how it looks like. When I do it with your code, it looks like

POST /url HTTP/1.1
Content-Length: 739
Content-Type: multipart/form-data; boundary=L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Host: 127.0.0.1:8090
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
Accept-Encoding: gzip,deflate

--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Content-Disposition: form-data; name="input1"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

data1
--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Content-Disposition: form-data; name="input2"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

data2
--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Content-Disposition: form-data; name="input3"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

data3
--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c
Content-Disposition: form-data; name="file"; filename="myFile.dat"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary


--L2EqtNqIEXOWRCYYrYH8FSP1JAD65wz6c--

which is not what you want. You only need a request with two parts, one is the json data and the other is the file.

So if you change your code as the following.

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost uploadFile = new HttpPost("http://localhost:8090/1");

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
String jsonStr = "{\"input1\":\"data1\",\"input2\":\"data2\",\"input3\":\"data3\"}";
builder.addTextBody("json", jsonStr, ContentType.APPLICATION_JSON);
builder.addBinaryBody("file", new File("/path/to/file"),
        ContentType.TEXT_PLAIN, "myFile.dat");

HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
HttpResponse response = httpClient.execute(uploadFile);

You can provide a request like the following.

POST /url HTTP/1.1
Content-Length: 468
Content-Type: multipart/form-data; boundary=mN_bWsS4QQnlPJksvinB_WUpl2Qi6zVVElUEEBKh
Host: 127.0.0.1:8090
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
Accept-Encoding: gzip,deflate

--mN_bWsS4QQnlPJksvinB_WUpl2Qi6zVVElUEEBKh
Content-Disposition: form-data; name="json"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit

{"input1":"data1","input2":"data2","input3":"data3"}
--mN_bWsS4QQnlPJksvinB_WUpl2Qi6zVVElUEEBKh
Content-Disposition: form-data; name="file"; filename="myFile.dat"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: binary


--mN_bWsS4QQnlPJksvinB_WUpl2Qi6zVVElUEEBKh--

which is what you need.

Sign up to request clarification or add additional context in comments.

Comments

0

For multipart request, the content-type has to be multipart/form-data, then you specify content-type for each content. You might want to refer to w3.org - Introduction to forms for the HTTP header examples.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.