HttpClient
是JDK11提供的一个全新HTTP客户端Api,超级好用。
Multipart 请求
HttpClient 并没有提供 Multipart 请求体的构建Api。但是可以使用apache的开源httpmime库来进行构建。
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.13</version>
</dependency>
构建一个 MultipartBody
// 构建Multipart请求
HttpEntity httpEntity = MultipartEntityBuilder.create()
// 表单数据
.addPart("name", new StringBody(UriUtils.encode("SpringBoot中文社区", StandardCharsets.UTF_8), ContentType.APPLICATION_FORM_URLENCODED))
// JSON数据
.addPart("info", new StringBody("{\"site\": \"https://springboot.io\", \"now\": 2021}", ContentType.APPLICATION_JSON))
// 文件数据
.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, "eclipse-jee-2019-12-R-win32-x86_64.zip")
.build();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream((int) httpEntity.getContentLength());
// 把body写入到内存
httpEntity.writeTo(byteArrayOutputStream);
Multipart 请求可以一次性post多个子body,通常用来上传本地磁盘上的文件。所以这种请求体可能会异常庞大。甚至内存不能完整的存入整个请求体。那么这个时候有2种办法可以解决。
- 先把构建好的Body数据写入到磁盘,再通过IO磁盘数据,提交给服务器
- 使用管道流,在读取磁盘数据进行body构建的时候,直接通过管道提交到远程服务器
管道流
管道流,顾名思义,可以往一边写,从另一边读。
// 创建读取流
PipedInputStream pipedInputStream = new PipedInputStream();
// 创建写入流
PipedOutputStream pipedOutputStream = new PipedOutputStream();