Загрузить файл с помощью @FeignClient в SpringBoot - PullRequest
1 голос
/ 11 июля 2020

У меня два приложения, оба на SpringBoot. Я пытаюсь загрузить файл из одного приложения в другое, используя @FeignClient

Вот код контроллера, который принимает загрузку файла

@PostMapping(
    path = "/result/output/{resultId}",
    consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseStatus(HttpStatus.OK)
public Result uploadOutputProviderMetadata(@PathVariable(value = "resultId") UUID resultId,
                                           @RequestParam("file") MultipartFile multipartFile) {
    return resultService.storeResult(providerSearchTaskId, getString(multipartFile));
}

Вот вызов тестового фрагмента для этого контроллера

new MockMultipartFile(
                "file",
                file.getName(),
                "application/zip",
                FileUtils.readFileToByteArray(file));
var resultAsString = getMockMvc()
                .perform(MockMvcRequestBuilders
                        .multipart("/private/api/v1/result/output/" + resultId.toString(), getPort())
                        .file(multipartFile)
                        .contentType(MediaType.MULTIPART_FORM_DATA)
                )
                .andExpect(status().isOk())
                .andReturn()
                .getResponse()
                .getContentAsString();

Тест работает, MvcMock может загружать файл, используя MockMultipartFile и MediaType.MULTIPART_FORM_DATA

Вот мой бедный FeignClient из другого приложения, которое пытается загрузить файл

@FeignClient(name = "Client", url = "${server.url}")
trait UploadClient {
  @PostMapping(
    path = Array("/private/api/v1/result/output/{resultId}"),
    consumes = Array(MediaType.MULTIPART_FORM_DATA_VALUE))
def uploadResult(@PathVariable resultId: UUID,
                   @RequestPart(name = "file") file: MultiValueMap[String, Object]): Result
  }
}



@Configuration
@EnableFeignClients(clients = Array(classOf[UploadClient]))
class FeignActivationConfiguration {

  @Bean
  def clientFeignEncoder(messageConverters: ObjectFactory[HttpMessageConverters]): Encoder = {
    new SpringFormEncoder(new SpringEncoder(messageConverters))
  }
}

У меня есть тест e2e и симуляция бросков

status 400 reading AdsManagerClient#uploadResult(UUID,MultiValueMap)
feign.FeignException$BadRequest: status 400 reading UploadClient#uploadResult(UUID,MultiValueMap)

Почему?

Я добавил декодер ошибок, контроллер не очень информативный

// Error response code: 400, responseText: ERROR, reason: null 

val errorMessage = s"Error response code: ${response.status()}, responseText: $responseText, reason: ${response.reason()} while calling  $methodKey"
...