使用RestTemplate发送多部分文件

时间:2019-01-25 13:09:35

标签: java spring resttemplate multipart

我有两个服务器,其中服务器A正在将文件发送到服务器B。在服务器B上,我有一个终结点,该终结点可以接收给定类别的文件。这是端点的签名,我需要将文件发送到:

@PostMapping("/uploadMultipleFiles/{projectId}")
public List<UploadFileResponseDts> uploadMultipleFiles(@RequestParam("files") MultipartFile[] files, @RequestParam("categoryId") Long categoryId, @PathVariable("projectId") Long projectId) {
    return uploadMulitpleFiles(files, categoryId, projectId);
}

现在我无法通过RestTemplate交换创建此类请求。在服务器A上,我尝试一个接一个地发送文件(服务器B上的端点也需要接受多部分数组,因为它也在其他地方使用)。这就是我尝试过的:

public Optional<String> uploadFile(File file, Long projectId) throws Exception {

    String authToken = getAccessToken();
    String projectFileUploadEndpoint = fileUploadEndpoint + SEPARATOR + projectId;

    FileInputStream input = new FileInputStream(file);
    byte[] bytes = IOUtils.toByteArray(input);

    MultiValueMap<String, Object> parts =
            new LinkedMultiValueMap<>();
            parts.add("files", new ByteArrayResource(bytes));
    parts.add("categoryId", 0L);

    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    headers.set("Authorization", authToken);

    HttpEntity<MultiValueMap<String, Object>> requestEntity =
            new HttpEntity<>(parts, headers);

    ResponseEntity<String> response =
            restTemplate.exchange(projectFileUploadEndpoint ,
                    HttpMethod.POST, requestEntity, String.class);

    return Optional.empty();
}

这几乎可以工作,唯一的问题是服务器B files上的@RequestParam("files") MultipartFile[] files始终为空。我认为问题在于在服务器A上组装parts的方式,但是我找不到我的错误。你能指出吗?

1 个答案:

答案 0 :(得分:0)

在您的控制器中一切正常,问题出在您的客户端代码上。

基本上,您应该使用FileSystemResource对象而不是ByteArrayResource。 基本动机是关于文件元数据。使用FileSystemResource spring可以重建所需的MultipartFile信息,因此您的代码可能如下所示

  @Test
  public void contextLoads()
  {
    File file = new File("test.txt");
    FileSystemResource fileSystemResource = new FileSystemResource(file);

    MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
    parts.add("categoryId", 0L);
    parts.add("files", fileSystemResource);

    String serviceUrl = "http://localhost:8080/uploadMultipleFiles/0";

    RequestEntity<MultiValueMap<String, Object>> requestEntity = post(fromPath(serviceUrl).build().toUri())
      .contentType(MediaType.MULTIPART_FORM_DATA)
      .body(parts);

    RestTemplate restTemplate = new RestTemplate();

    restTemplate.setErrorHandler(new ResponseErrorHandler()
    {
      @Override
      public boolean hasError(ClientHttpResponse response) throws IOException
      {
        return false;
      }

      @Override
      public void handleError(ClientHttpResponse response) throws IOException
      {
        System.out.println(response);
      }
    });
    ResponseEntity<String> response = restTemplate.exchange(serviceUrl, HttpMethod.POST, requestEntity, String.class);

    assertThat(200, Is.is(response.getStatusCode()));

  }

我希望这个测试案例可以帮助您解决问题