Отправка многокомпонентных файлов с помощью RestTemplate - PullRequest
0 голосов
/ 25 января 2019

У меня есть два сервера, где сервер 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 всегда ноль.Я предполагаю, что проблема в том, как я собираю parts на моем сервере A, однако я не могу найти свою ошибку.Не могли бы вы указать на это?

1 Ответ

0 голосов
/ 28 июля 2019

в вашем контроллере все в порядке, проблема в коде вашего клиента.

В основном вы должны использовать 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()));

  }

Я надеюсь, что этот тестовый пример поможет вам решить проблему

...