首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过WebClient发送包含字节数组的POST请求?

如何通过WebClient发送包含字节数组的POST请求?
EN

Stack Overflow用户
提问于 2022-03-29 09:33:03
回答 1查看 2.6K关注 0票数 1

我希望通过POST方法通过WebClient发送文件请求,并且需要以byte[]的形式发送文件以获得正确的响应。我将MultipartFile file设置为byte[],然后我认为我需要使用BodyInserters来使这个主体包含byte[],但我不知道如何使请求体。

如何通过WebClient发送包含字节数组的POST请求

代码语言:javascript
运行
复制
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;

@RestController
public class ApiController {
  @PostMapping(value = "/update")
  public String update(@RequestParam("file") MultipartFile file, @RequestParam("uri") String uri ) {
    String result = "{error : error}";
    byte[] byteArr;
    BodyInserters byteArrInserter;
    try {
      byteArr = file.getBytes();
      A? publisher = B?.C?; // I don't know what will be right for those A?, B?, C?
      byteArrInserter = BodyInserters.fromDataBuffers(publisher); // In fact, I'm not sure this method will be good for this situation, either.
    } catch (Exception e) {
      System.out.println(e);
    }

    WebClient client = WebClient.builder()
      .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize( 1024*1024*1024 * 2)) // 2GB
      .build();
    try {
      result = client
        .post()
        .uri(uri)
        .body(byteArrInserter)
        .retrieve().bodyToMono(String.class).block();
    } catch (Exception e) {
      System.out.println(e);
    }
    return result;
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-29 10:10:35

我不知道如何用WebClient发送二进制内容,但是还有一些其他选项。首先,有SpringBoot自己的RestTemplate类,它是WebClient的替代品。这里有一篇关于两者的比较文章:Spring WebClient vs.。如果您希望使用绝对能够发送二进制内容的第三方Http客户端,您可以查看两个流行的选项:

  1. Apache Http客户端
  2. 好的Http客户端

最后,我编写了自己的Http客户机,它是我编写和维护的开源MgntUtils库的一部分。这个Http客户端非常简单,但是可以完成这项工作。实际上,我正在添加允许上传二进制信息的功能。我还没有发布它,但是您可以下载分支,或者查看我在那里的代码。分支位于这里,HttpClient类是这里。见法

public String sendHttpRequest(String requestUrl, HttpMethod callMethod, ByteBuffer data) throws IOException

在第162行。我测试此方法的方法如下所示:

代码语言:javascript
运行
复制
private static void testHttpClientBinaryUpload() {
    try {
        byte[] content = Files.readAllBytes(Paths.get("C:\\Michael\\Personal\\pics\\testPic.jpg"));
        HttpClient client = new HttpClient();
        Integer length = content.length;
        Files.write(Paths.get("C:\\Michael\\tmp\\testPicOrig.jpg"), content);
        client.setRequestHeader("Content-Length", length.toString());
        String result = client.sendHttpRequest("http://localhost:8080/upload", HttpMethod.POST, ByteBuffer.wrap(content));
        System.out.println(result);
        System.out.println("HTTP " + client.getLastResponseCode() + " " + client.getLastResponseMessage());
    } catch (Exception e) {
        System.out.println(TextUtils.getStacktrace(e, "com.mgnt."));
    }
}

接收请求的服务器端Springboot rest控制器如下所示:

代码语言:javascript
运行
复制
 @RestController
@RequestMapping("/upload")
public class UploadTestController {
    @PostMapping
    public ResponseEntity<String> uploadTest(HttpServletRequest request) {
        try {
            String lengthStr = request.getHeader("content-length");
            int length = TextUtils.parseStringToInt(lengthStr, -1);
            if(length > 0) {
                byte[] buff = new byte[length];
                ServletInputStream sis =request.getInputStream();
                int counter = 0;
                while(counter < length) {
                    int chunkLength = sis.available();
                    byte[] chunk = new byte[chunkLength];
                    sis.read(chunk);
                    for(int i = counter, j= 0; i < counter + chunkLength; i++, j++) {
                        buff[i] = chunk[j];
                    }
                    counter += chunkLength;
                    if(counter < length) {
                        TimeUtils.sleepFor(5, TimeUnit.MILLISECONDS);
                    }
                }
                Files.write(Paths.get("C:\\Michael\\tmp\\testPic.jpg"), buff);
            }
        } catch (Exception e) {
            System.out.println(TextUtils.getStacktrace(e));
        }
        return ResponseEntity.ok("Success");
    }
}

我计划在几天内出版新版本的图书馆,这个功能将包括在内。无论如何,这里是指向Maven伪像GithubJavadoc的链接。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71659626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档