100

I need to receive an HTTP Post Multipart which contains only 2 parameters:

  • A JSON string
  • A binary file

Which is the correct way to set the body? I'm going to test the HTTP call using Chrome REST console, so I'm wondering if the correct solution is to set a "label" key for the JSON parameter and the binary file.

On the server side I'm using Resteasy 2.x, and I'm going to read the Multipart body like this:

@POST
@Consumes("multipart/form-data")
public String postWithPhoto(MultipartFormDataInput  multiPart) {
  Map <String, List<InputPart>> params = multiPart.getFormDataMap();
  String myJson = params.get("myJsonName").get(0).getBodyAsString();
  InputPart imagePart = params.get("photo").get(0);
  //do whatever I need to do with my json and my photo
}

Is this the way to go? Is it correct to retrieve my JSON string using the key "myJsonName" that identify that particular content-disposition? Are there any other way to receive these 2 content in one HTTP multipart request?

starball
  • 20,030
  • 7
  • 43
  • 238
thermz
  • 2,386
  • 3
  • 20
  • 28
  • 1
    What kind of REST resource is this? How do two parts relate on the resource level? –  Jan 31 '12 at 14:21
  • Actually the way we handled this resource is not totally RESTful because the image is a "component" of the resource instead of another resource. – thermz Jan 31 '12 at 14:25

1 Answers1

161

If I understand you correctly, you want to compose a multipart request manually from an HTTP/REST console. The multipart format is simple; a brief introduction can be found in the HTML 4.01 spec. You need to come up with a boundary, which is a string not found in the content, let’s say HereGoes. You set request header Content-Type: multipart/form-data; boundary=HereGoes. Then this should be a valid request body:

--HereGoes
Content-Disposition: form-data; name="myJsonString"
Content-Type: application/json

{"foo": "bar"}
--HereGoes
Content-Disposition: form-data; name="photo"
Content-Type: image/jpeg
Content-Transfer-Encoding: base64

<...JPEG content in base64...>
--HereGoes--
Vasiliy Faronov
  • 11,840
  • 2
  • 38
  • 49
  • You can actually add an attachment in soap-ui too. This alleviates having to pass in the actual post body and the content-type. – shane lee Mar 28 '14 at 00:37
  • 1
    Is there a standardized way for coming up with the unique boundary? – andig Mar 11 '15 at 17:26
  • 2
    @andig I’m not aware of any. Perhaps you could use a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), but that’s not necessarily a good idea. Normally your HTTP library should take care of that for you. – Vasiliy Faronov Mar 12 '15 at 20:30
  • If we know we only have json and base64 data in the request shouldn't something like `\*` for example work as a boundary? It's neither allowed to exist in json nor base64. – DaedalusAlpha Nov 10 '16 at 17:32
  • @DaedalusAlpha [RFC 2046 § 5.1.1](https://tools.ietf.org/html/rfc2046#section-5.1.1) disallows such a boundary string (see the `bcharsnospace` rule). Also note that `"\\*"` is valid JSON. – Vasiliy Faronov Nov 10 '16 at 22:31
  • 3
    Why use base64 to encode the JPEG data? HTTP allows you to send the raw bytes. – Alexandre Blin Feb 09 '17 at 17:50
  • @AlexandreBlin The question involved sending a request manually from some sort of GUI REST console. It’s usually not a good idea to paste raw JPEG bytes into a GUI. – Vasiliy Faronov Feb 09 '17 at 18:59
  • Excellent. With reference to node, following is explained in detail: http://derpturkey.com/node-multipart-form-data-explained/ – Sourabh Apr 09 '19 at 03:36