RestTemplate directly sends memory file object multipart

1. RestTemplate directly sends the memory file object multipart

1. Create a byte array output stream object and use the write method of the Word document object to write its content to the stream

2. Use Spring’s RestTemplate to send POST requests containing attachments.

Use HttpHeaders to set multipart/form-data headers:
Then, a resource object consisting of a byte array and other information (such as the original file name and media type) is constructed for use as part of the HTTP request. Then, construct a MultiValueMap object to hold the file and other form data:
Finally, send the request using RestTemplate’s exchange or postForEntity methods:

public void uploadDoc(XWPFDocument document, ReportMessage reportMessage) {<!-- -->
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {<!-- -->
      document.write(out);
    } catch (IOException e) {<!-- -->
      throw new RuntimeException(e);
    }

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    String fileName = "report-" + reportMessage.getReportId() + ".docx";
    ByteArrayResource resource =
        new ByteArrayResource(out.toByteArray()) {<!-- -->
          @Override
          public String getFilename() {<!-- -->
            return fileName;
          }
        };

    MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
    body.add("file", new HttpEntity<>(resource, headers));
    body.add("reportId", reportMessage.getReportId());

    ResponseEntity<String> response = restTemplate.postForEntity(upLoadUrl, body, String.class);

    log.info(response.getBody());
  }

The following quote https://www.yixuebiancheng.com/article/101586.html

2. The uploaded file is of File type

If the file is saved locally, the specified file can be obtained through File file = new File(path) or the file path address.

public String uploadFile(File file) {<!-- -->
    // 1. Encapsulate request header
    HttpHeaders headers = new HttpHeaders();
    MediaType type = MediaType.parseMediaType("multipart/form-data");
    headers.setContentType(type);
    headers.setContentLength(file.length());
    headers.setContentDispositionFormData("media", file.getName());
    // 2. Encapsulate the request body
    MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
    FileSystemResource resource = new FileSystemResource(file);
    param.add("file", resource);
    // 3. Encapsulate the entire request message
    HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(param, headers);
    // 4. Send request
    ResponseEntity<String> data = restTemplate.postForEntity(tempMaterialUploadUrl, formEntity, String.class);
    // 5. Request result processing
    JSONObject weChatResult = JSONObject.parseObject(data.getBody());
    return weChatResult;
}

This method can directly pass the File file or file path to the FileSystemResource resource object. Then put the resource into the request body.

3. The uploaded file is an InputStream

If the file does not exist locally, but is in Alibaba Cloud OSS or other files that can only be obtained through the URL, and you do not want to save the file locally but send it directly through restTemplate, you can use the following method.

Example: I use this example at work: I upload the attachments uploaded by the system to Alibaba Cloud OSS through the Alibaba Cloud API, and then I need to save the files to the enterprise WeChat server, and the system server does not store any attachments, so I use the following Method, obtain the uploaded attachment A through the Alibaba Cloud API in the form of InputStream, and then upload the input stream to the enterprise WeChat server.

public String uploadInputStream(InputStream inputStream,String fileName,long cententLength) {<!-- -->
    // 1. Encapsulate request header
    HttpHeaders headers = new HttpHeaders();
    MediaType type = MediaType.parseMediaType("multipart/form-data");
    headers.setContentType(type);
    headers.setContentDispositionFormData("media", fileName);
    // 2. Encapsulate the request body
    MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
    InputStreamResource resource = new InputStreamResource(inputStream){<!-- -->
        @Override
        public long contentLength(){<!-- -->
            return cententLength;
        }
        @Override
        public String getFilename(){<!-- -->
            return fileName;
        }
    };
    param.add("file", resource);
    // 3. Encapsulate the entire request message
    HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(param, headers);
    // 4. Send request
    ResponseEntity<String> data = restTemplate.postForEntity(tempMaterialUploadUrl, formEntity, String.class);
    // 5. Request result processing
    JSONObject weChatResult = JSONObject.parseObject(data.getBody());
    // 6. Return the result
    return weChatResult;
}

When an input stream is required to upload a file, you need to use InputStreamResource to build the resource file. Be careful to override the contentLength() and getFilename() methods, otherwise it will not succeed. As for the fileName and contentLength in the parameters, they must be obtained in advance through the URL of the file. Because I read the file from Alibaba Cloud OSS, I can directly obtain the file size and file name.

4. The file uploaded is MultipartFile type file

Sometimes we need to directly upload the files received by SpringMVC through the MultipartFile type to the system. In this case, we can use the following method to solve the problem.

public String uploadFileWithInputStream(MultipartFile file) throws IOException {<!-- -->
    // 1. Encapsulate request header
    HttpHeaders headers = new HttpHeaders();
    MediaType type = MediaType.parseMediaType("multipart/form-data");
    headers.setContentType(type);
    headers.setContentLength(file.getSize());
    headers.setContentDispositionFormData("media", file.getOriginalFilename());
    // 2. Encapsulate the request body
    MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
    // Convert multipartFile into byte resources for transmission
    ByteArrayResource resource = new ByteArrayResource(file.getBytes()) {<!-- -->
        @Override
        public String getFilename() {<!-- -->
            return file.getOriginalFilename();
        }
    };
    param.add("file", resource);
    // 3. Encapsulate the entire request message
    HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(param, headers);
    // 4. Send request
    ResponseEntity<String> data = restTemplate.postForEntity(tempMaterialUploadUrl, formEntity, String.class);
    // 5. Request result processing
    JSONObject weChatResult = JSONObject.parseObject(data.getBody());
    // 6. Return the result
    return weChatResult;
}

Note: When using ByteArrayResource to build resources, you should override the getFilename() method of ByteArrayResource, otherwise it will not succeed.