diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java index f52f570f2..12a14e699 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java @@ -3,7 +3,6 @@ package cn.hutool.http; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.IORuntimeException; -import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.resource.BytesResource; import cn.hutool.core.io.resource.FileResource; import cn.hutool.core.io.resource.MultiFileResource; @@ -12,18 +11,19 @@ import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; import cn.hutool.core.net.SSLUtil; import cn.hutool.core.net.url.UrlBuilder; -import cn.hutool.core.net.url.UrlQuery; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.http.body.BytesBody; +import cn.hutool.http.body.FormUrlEncodedBody; import cn.hutool.http.body.MultipartBody; +import cn.hutool.http.body.RequestBody; import cn.hutool.http.cookie.GlobalCookieManager; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSocketFactory; import java.io.File; import java.io.IOException; -import java.io.OutputStream; import java.net.CookieManager; import java.net.HttpCookie; import java.net.HttpURLConnection; @@ -1212,23 +1212,13 @@ public class HttpRequest extends HttpBase { } // Write的时候会优先使用body中的内容,write时自动关闭OutputStream - byte[] content; + RequestBody body; if (ArrayUtil.isNotEmpty(this.bodyBytes)) { - content = this.bodyBytes; + body = BytesBody.create(this.bodyBytes); } else { - content = StrUtil.bytes(getFormUrlEncoded(), this.charset); + body = FormUrlEncodedBody.create(this.form, this.charset); } - IoUtil.write(this.httpConnection.getOutputStream(), true, content); - } - - /** - * 获取编码后的表单数据,无表单数据返回"" - * - * @return 编码后的表单数据,无表单数据返回"" - * @since 5.3.2 - */ - private String getFormUrlEncoded() { - return UrlQuery.of(this.form, true).build(this.charset); + body.writeClose(this.httpConnection.getOutputStream()); } /** @@ -1238,18 +1228,9 @@ public class HttpRequest extends HttpBase { * @throws IOException IO异常 */ private void sendMultipart() throws IOException { - setMultipart();// 设置表单类型为Multipart - - try (OutputStream out = this.httpConnection.getOutputStream()) { - MultipartBody.create(this.form, this.charset).write(out); - } - } - - /** - * 设置表单类型为Multipart(文件上传) - */ - private void setMultipart() { + //设置表单类型为Multipart(文件上传) this.httpConnection.header(Header.CONTENT_TYPE, MultipartBody.getContentType(), true); + MultipartBody.create(this.form, this.charset).writeClose(this.httpConnection.getOutputStream()); } /** diff --git a/hutool-http/src/main/java/cn/hutool/http/body/BytesBody.java b/hutool-http/src/main/java/cn/hutool/http/body/BytesBody.java new file mode 100644 index 000000000..138b48f3a --- /dev/null +++ b/hutool-http/src/main/java/cn/hutool/http/body/BytesBody.java @@ -0,0 +1,39 @@ +package cn.hutool.http.body; + +import cn.hutool.core.io.IoUtil; + +import java.io.OutputStream; + +/** + * bytes类型的Http request body,主要发送编码后的表单数据或rest body(如JSON或XML) + * + * @since 5.7.17 + * @author looly + */ +public class BytesBody implements RequestBody { + + private final byte[] content; + + /** + * 创建 Http request body + * @param content body内容,编码后 + * @return BytesBody + */ + public static BytesBody create(byte[] content){ + return new BytesBody(content); + } + + /** + * 构造 + * + * @param content Body内容,编码后 + */ + public BytesBody(byte[] content) { + this.content = content; + } + + @Override + public void write(OutputStream out) { + IoUtil.write(out, false, content); + } +} diff --git a/hutool-http/src/main/java/cn/hutool/http/body/FormUrlEncodedBody.java b/hutool-http/src/main/java/cn/hutool/http/body/FormUrlEncodedBody.java new file mode 100644 index 000000000..aa675b0a2 --- /dev/null +++ b/hutool-http/src/main/java/cn/hutool/http/body/FormUrlEncodedBody.java @@ -0,0 +1,38 @@ +package cn.hutool.http.body; + +import cn.hutool.core.net.url.UrlQuery; +import cn.hutool.core.util.StrUtil; + +import java.nio.charset.Charset; +import java.util.Map; + +/** + * application/x-www-form-urlencoded 类型请求body封装 + * + * @author looly + * @since 5.7.17 + */ +public class FormUrlEncodedBody extends BytesBody { + + /** + * 创建 Http request body + * + * @param form 表单 + * @param charset 编码 + * @return FormUrlEncodedBody + */ + public static FormUrlEncodedBody create(Map form, Charset charset) { + return new FormUrlEncodedBody(form, charset); + } + + /** + * 构造 + * + * @param form 表单 + * @param charset 编码 + */ + public FormUrlEncodedBody(Map form, Charset charset) { + super(StrUtil.bytes(UrlQuery.of(form, true).build(charset), charset)); + } + +} diff --git a/hutool-http/src/main/java/cn/hutool/http/body/RequestBody.java b/hutool-http/src/main/java/cn/hutool/http/body/RequestBody.java index 16b6a04e4..76fb9b378 100644 --- a/hutool-http/src/main/java/cn/hutool/http/body/RequestBody.java +++ b/hutool-http/src/main/java/cn/hutool/http/body/RequestBody.java @@ -1,5 +1,7 @@ package cn.hutool.http.body; +import cn.hutool.core.io.IoUtil; + import java.io.OutputStream; /** @@ -13,4 +15,18 @@ public interface RequestBody { * @param out out流 */ void write(OutputStream out); + + /** + * 写出并关闭{@link OutputStream} + * + * @param out {@link OutputStream} + * @since 5.7.17 + */ + default void writeClose(OutputStream out) { + try { + write(out); + } finally { + IoUtil.close(out); + } + } }