【问题标题】:Spring Webclient multipart/form-data requestSpring Webclient 多部分/表单数据请求
【发布时间】:2020-03-23 22:22:29
【问题描述】:

我是 Java (Spring Boot) 新手,我正在尝试向 s3 发送 multipart/form-data POST 请求以上传文件。

我设法使用 spring 的RestTemplate 做到了这一点:

    public String uploadFile(byte[] file, Map<String, Object> fields, String url) throws URISyntaxException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        MultiValueMap<String, Object> formData= new LinkedMultiValueMap<String, Object>();
        for (Map.Entry<String, Object> entry : fields.entrySet()) {
            formData.add(entry.getKey(), entry.getValue());
        }
        formData.add("file", file);
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<MultiValueMap<String, Object>>(formData, headers);
        String response = restTemplate.postForObject(new URI(url), request, String.class);
        return response;
    }

然后我尝试使用webclient 做同样的事情,但我不能,AWS 回复The body of your POST request is not well-formed multipart/form-data.

这是使用 webclient 的代码:

    public String uploadFileWebc(byte[] file, Map<String, Object> fields, String url) {

        MultipartBodyBuilder builder = new MultipartBodyBuilder();
        for (Map.Entry<String, Object> entry : fields.entrySet()) {
            builder.part(entry.getKey(), entry.getValue(), MediaType.TEXT_PLAIN);
        }

        builder.part("file", file).filename("file");
        MultiValueMap<String, HttpEntity<?>> parts = builder.build();


        Void result = webClient.filter(errorHandlingFilter()).build().post().uri(url)
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .contentLength(file.length)
                .bodyValue(parts)
                .retrieve()
                .bodyToMono(Void.class)
                .block();
        return "Done Uploading.";
    }

谁能指出我错过了什么?

【问题讨论】:

  • 可能不是问题,但是您将空的 MultiValueMap 传递给 bodyValue 方法而不是您的多部分主体,这很可能是您的问题所在......另外,您不应该自己设置内容长度,Web客户端/休息模板会自动添加它,公式并不像你输入的file.length那么简单,因为你在那个映射中有其他参数,而file条目本身就是一个参数意味着它有一个额外的标题。

标签: spring-boot multipartform-data spring-webflux pre-signed-url spring-webclient


【解决方案1】:

原来webclient由于其流式特性而没有添加content-length标头,而S3 API需要发送此标头。

我最终使用restTemplate 将文件上传到 S3。

【讨论】:

  • 你能分享一下你正在使用的 webclient 对象存在于哪个包中吗?
猜你喜欢
  • 2020-10-12
  • 2012-11-27
  • 2016-12-17
  • 2012-03-16
  • 2016-11-11
  • 2013-02-12
  • 2018-07-02
  • 2017-10-05
相关资源
最近更新 更多