У меня два приложения, оба на 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"