Content type multipart form data java

How to send multipart/form-data requests via HttpClient

HttpClient is a new client tool class provided by JDK11 under the java.net.http package. This article will teach you how to send multipart/form-data requests through HttpClient.

multipart/form-data

The types in the MIME standard can be divided into two categories: standalone types and Multipart types.

Standalone type is a type that represents only a single file or media, indicating the classification of files for the transferred data. Examples include text , application , audio , image , video , etc. Multipart type, on the other hand, specifies that the data being transferred can be divided into several separate blocks of data, each of which can have its own separate meaning and MIME type.

Multipart/form-data is the most common subtype of the Multipart type. Most commonly used in HTTP POST requests for form data and file uploads, the multipart/form-data format was first defined in the RFC2388 specification published in 1998. This specification was superseded in 2015 by the newly released RFC7578 specification.

Java does not provide a ready-made encoding tool class for multipart/form-data , so you need to use a third-party implementation. Here we recommend using the apache open source httpmime toolkit. Next I will show a demo of using HttpClient to send a file upload request.

    org.apache.httpcomponents   httpmime  

Demo

Server

A very simple controller that handles the file uploaded by the client, as well as the JSON and form data submitted at the same time. If the output log is correct, then the client has successfully sent the multipart/form-data request.

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 
package io.springboot.demo.web.controller;  import java.io.IOException; import java.io.InputStream;  import org.springframework.http.MediaType; import org.springframework.util.StreamUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile;  import com.google.gson.JsonObject;  import lombok.extern.slf4j.Slf4j;  @RestController @RequestMapping("/upload") @Slf4j public class UploadController    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.TEXT_PLAIN_VALUE)  public Object upload(@RequestPart("logo") MultipartFile logo,  @RequestPart("name") String name,  @RequestPart("info") JsonObject info) throws IOException    log.info("name = <>", name);  log.info("info = <>", info);  log.info("logo = contentType: <>, fileName: <>, formName: <>, size: <>", logo.getContentType(),  logo.getOriginalFilename(), logo.getName(), logo.getSize());   try (InputStream inputStream = logo.getInputStream())  StreamUtils.drain(inputStream);  >   return "ok";  > > 

Client

Use MultipartEntityBuilder to create a Multipart request body, which contains a file, a form data and a JSON data. And write to the network using a pipeline stream to avoid memory overflow due to oversized request bodies.

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 
package io.springcloud.test;  import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.nio.channels.Channels; import java.nio.channels.Pipe; import java.nio.charset.StandardCharsets;  import org.apache.http.HttpEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.StringBody;  public class MultipartRequest    public static void main(String[] args) throws Exception    /**  * Create a Multipart request body with MultipartEntityBuilder.  */  HttpEntity httpEntity = MultipartEntityBuilder.create()  // FORM  .addPart("name",  new StringBody("",  ContentType.create("application/x-www-form-urlencoded", StandardCharsets.UTF_8)))  // JSON  .addPart("info",  new StringBody("", ContentType.APPLICATION_JSON))  // FILE  .addBinaryBody("logo", new File("C:\\Users\\KevinBlandy\\Desktop\\logo.png"), ContentType.IMAGE_PNG,  "logo.png")  .build();   /**  * Use pipeline streams to write the encoded data directly to the network  * instead of caching it in memory. Because Multipart request bodies contain  * files, they can cause memory overflows if cached in memory.  */  Pipe pipe = Pipe.open();   // Pipeline streams must be used in a multi-threaded environment. Using one  // thread for simultaneous reads and writes can lead to deadlocks.  new Thread(() ->   try (OutputStream outputStream = Channels.newOutputStream(pipe.sink()))   // Write the encoded data to the pipeline.  httpEntity.writeTo(outputStream);  > catch (IOException e)   e.printStackTrace();  >   >).start();   HttpClient httpClient = HttpClient.newHttpClient();   HttpRequest request = HttpRequest.newBuilder(new URI("http://localhost/upload"))  // The Content-Type header is important, don't forget to set it.  .header("Content-Type", httpEntity.getContentType().getValue())  // Reads data from a pipeline stream.  .POST(BodyPublishers.ofInputStream(() -> Channels.newInputStream(pipe.source()))).build();   HttpResponseString> responseBody = httpClient.send(request, BodyHandlers.ofString(StandardCharsets.UTF_8));   System.out.println(responseBody.body());  > > 

Testing

Start the server first, before running the client.

2022-04-27 15:52:58.834 INFO 8392 --- [ XNIO-1 task-1] i.s.d.web.controller.UploadController : name = 2022-04-27 15:52:58.834 INFO 8392 --- [ XNIO-1 task-1] i.s.d.web.controller.UploadController : info = 2022-04-27 15:52:58.834 INFO 8392 --- [ XNIO-1 task-1] i.s.d.web.controller.UploadController : logo = contentType: image/png, fileName: logo.png, formName: logo, size: 17389 

As you can see, the client successfully sent the multipart/form-data request.

Источник

Читайте также:  Java date minus minute
Оцените статью