Below is a form:
While the correct answer is full-blown implementation and might be correct, it did not work for me.
My solution took inspiration from here. I just cleaned up for my use case not required parts. Me, personally, use multipart form for only uploading picture or zip file (singular). The code:
public static HttpRequest buildMultiformRequest(byte[] body) {
String boundary = "-------------" + UUID.randomUUID().toString();
Map data = Map.of("formFile", body);
return HttpRequest.newBuilder()
.uri(URI.create())
.POST(HttpRequest.BodyPublishers.ofByteArrays(buildMultipartData(data, boundary, "filename.jpeg", MediaType.IMAGE_JPEG_VALUE)))
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.header("Accept", MediaType.APPLICATION_JSON_VALUE)
.timeout(Duration.of(5, ChronoUnit.SECONDS))
.build();
}
public static ArrayList buildMultipartData(Map data, String boundary, String filename, String mediaType) {
var byteArrays = new ArrayList();
var separator = ("--" + boundary + "\r\nContent-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8);
for (var entry : data.entrySet()) {
byteArrays.add(separator);
byteArrays.add(("\"" + entry.getKey() + "\"; filename=\"" + filename + "\"\r\nContent-Type:" + mediaType + "\r\n\r\n").getBytes(StandardCharsets.UTF_8));
byteArrays.add(entry.getValue());
byteArrays.add("\r\n".getBytes(StandardCharsets.UTF_8));
}
byteArrays.add(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8));
return byteArrays;
}