【问题标题】:Okhttp create MultipartBody with spring MultipartFile and json objectOkhttp 使用 spring MultipartFile 和 json 对象创建 MultipartBody
【发布时间】:2020-06-21 11:56:10
【问题描述】:

我有一个这样的控制器,它接受 MultipartFile 和 json 对象:

@PostMapping(value = "/v1/submit")
    public ResponseEntity submit(
              @RequestParam(value="myFile", required = true) MultipartFile myFile
            , @Valid @RequestPart(value="fileMeta", required=true) FileMeta fileMeta
    ){

我需要使用包含 myFile 和 fileMeta 对象的 Multipartbody 的 okhttpclient 帖子将其转发到新 url:

OkHttpClient client = new OkHttpClient();
MultipartBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("myFile", myFile.getName(), okhttp3.RequestBody.create(file, MediaType.parse("pdf"))
                .addFormDataPart("fileMeta", fileMeta)
                .build();

我收到以下错误: 无法解析方法'create(org.springframework.web.multipart.MultipartFile, okhttp3.MediaType)'

【问题讨论】:

    标签: spring-boot multipartform-data okhttp


    【解决方案1】:

    OkHttp的RequestBodycreate的方法定义如下:create(MediaType contentType, byte[] content)。它需要第一个 MediaType 和第二个有效负载(byte[]File 或其他 formats)。

    因此,您首先必须切换方法参数的顺序,然后将 MultipartFile 从 Spring 转换为 create() 方法接受的正确格式,例如byte[]File:

    OkHttpClient client = new OkHttpClient();
    MultipartBody requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("myFile", myFile.getName(), RequestBody.create(MediaType.parse("pdf"), file)
                    .addFormDataPart("fileMeta", fileMeta)
                    .build();
    

    StackOverflow 上已经有多种解决方案可以将MultipartFile 转换为FileHow to convert a multipart file to File?

    UPDATE:使用RestTemplate的示例

    @RestController
    public class FileSendingController {
    
      @PostMapping("/files")
      public void streamFile(@RequestParam("file") MultipartFile file) {
    
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("file", file);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
    
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.postForEntity("http://upload.to", requestEntity, String.class);
      }
    }
    

    【讨论】:

    • 谢谢@rieckpil,我认为这可能是唯一的方法。由于转换,这肯定会导致处理时间的大量开销。没有其他方法可以做到这一点吗?也许 okhttp 团队可以研究一下?
    • 您可以使用 Spring RestTemplate 并使用它来进行 HTTP 调用。我不确定 OkHttp 团队是否愿意花时间来支持特定框架的文件格式
    • Spring RestTemplate 还“让你”在本地存储文件,然后才能转发。肯定有技术原因,okhttp 或 Spring RestTemplate 都不能让文件向前路由或在内存中传递。
    • 我认为这不是真的。互联网上的大多数示例仅提供有关如何使用本地文件执行此操作的教程。您应该能够在内存中执行此操作
    • 你有我可以使用的内存中的具体示例(例如流式传输)吗?
    猜你喜欢
    • 1970-01-01
    • 2021-07-16
    • 2017-11-14
    • 2019-07-17
    • 2013-01-29
    • 2016-10-27
    • 2023-03-30
    • 1970-01-01
    • 2018-07-03
    相关资源
    最近更新 更多