如何使用Spring RestTemplate发送multipartFile?

时间:2019-03-13 09:37:47

标签: spring spring-boot multipartform-data resttemplate

我正在尝试将文件从一个SpringBoot应用程序发布到另一个SpringBoot应用程序。 我要达到的目标看起来像

@PostMapping(
        value = "/upload",
        consumes = MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<ArmResponse<JobData>> uploadInvoices(@RequestParam("file") MultipartFile interestingStuff) {

    String incomingFilename = interestingStuff.getName();
    String originalFilename = interestingStuff.getOriginalFilename();
    String contentType = interestingStuff.getContentType();

    // do interesting stuff here

    return ok(successfulResponse(new JobData()));
}

执行对thios端点的POST请求的应用程序中的代码如下

public void loadInvoices(MultipartFile invoices) throws IOException {

    File invoicesFile = new File(invoices.getOriginalFilename());
    invoices.transferTo(invoicesFile);

    LinkedMultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
    parts.add("file", invoicesFile);


    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<LinkedMultiValueMap<String, Object>> httpEntity = new HttpEntity<>(parts, httpHeaders);

    String url = String.format("%s/rest/inbound/invoices/upload", baseUrl);

    final List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
    messageConverters.add(new ByteArrayHttpMessageConverter());
    messageConverters.add(new ResourceHttpMessageConverter());
    messageConverters.add(new AllEncompassingFormHttpMessageConverter());
    messageConverters.add(new FormHttpMessageConverter());
    messageConverters.add(new SourceHttpMessageConverter<Source>());

    RestTemplate template = new RestTemplate(messageConverters);

    template.exchange(
            url,
            HttpMethod.POST,
            httpEntity,
            new ParameterizedTypeReference<ArmResponse<JobData>>() {

            });
}

如果我使用邮递员以表格形式发布文件-它可以工作 来自邮递员的请求中的内容类型标头看起来像

content-type:"multipart/form-data; boundary=--------------------------286899320410555838190774"

RestTemplate执行POST时,出现以下错误。

com.fasterxml.jackson.databind.exc.MismatchedInputException:由于[Source:(String)“”;行:1,列:0]

我怀疑请求中发送的内容类型标头是错误的。 有谁知道如何正确设置MULTIPART_FORM_DATA的内容类型标头?

3 个答案:

答案 0 :(得分:0)

您为什么需要messageConverters?只需使用本教程中的代码即可:https://www.baeldung.com/spring-rest-template-multipart-upload

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate
  .postForEntity(url , httpEntity, String.class);

答案 1 :(得分:0)

与往常一样,该解决方案非常简单。只需在multipartFile上调用getResource()。

public void loadInvoices(MultipartFile invoices) throws IOException {

    Resource invoicesResource = invoices.getResource();

    LinkedMultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
    parts.add("file", invoicesResource);

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<LinkedMultiValueMap<String, Object>> httpEntity = new HttpEntity<>(parts, httpHeaders);

    restTemplate.postForEntity("my/url", httpEntity, SommeClass.class);
}

答案 2 :(得分:0)

Kotlin 中稍微漂亮的解决方案:

    @Test
    fun testMultipartUpload() {
        val bytes = ByteArray(10240) // Get your bytes however you like.
        val resource = object : ByteArrayResource(bytes) {
            override fun getFilename() = "xyzzy.jpg"
        }
        val request = RequestEntity.post("/foobar")
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(LinkedMultiValueMap<String, Any>().apply { add("data", resource) })
        val result = testRestTemplate.exchange(request, FooBar::class.java)
        Assertions.assertTrue(result.statusCode.is2xxSuccessful)
    }