From 0d11f82ee8370027edfc3414051ad4d0dde4f634 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 3 Mar 2023 20:25:27 +0800 Subject: [PATCH] =?UTF-8?q?HttpRequest#body=E5=A2=9E=E5=8A=A0=E6=94=AF?= =?UTF-8?q?=E6=8C=81Resource=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 +- .../main/java/cn/hutool/http/HttpBase.java | 9 ++-- .../main/java/cn/hutool/http/HttpRequest.java | 30 +++++++++---- .../java/cn/hutool/http/HttpResponse.java | 12 +++--- .../cn/hutool/http/body/ResourceBody.java | 42 +++++++++++++++++++ .../test/java/cn/hutool/http/RestTest.java | 16 +++---- 6 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 hutool-http/src/main/java/cn/hutool/http/body/ResourceBody.java diff --git a/CHANGELOG.md b/CHANGELOG.md index d3a5bd201..6f7192ea7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,13 @@ ------------------------------------------------------------------------------------------------------------- -# 5.8.13.M1 (2023-02-28) +# 5.8.13.M1 (2023-03-03) ### 🐣新特性 * 【core 】 PhoneUtil.isTel400800支持400-XXX-XXXX格式(issue#2929@Github) * 【core 】 build(pom): 添加 Automatic-Module-Name属性(pr#2926@Github) * 【core 】 根据JDK-8080225修改了部分新建文件输入流和文件输出流的创建方式(pr#2930@Github) +* 【http 】 HttpRequest#body增加支持Resource重载(issue#2901@Github) ### 🐞Bug修复 * 【db 】 修复识别JDBC驱动时重复问题(pr#940@Gitee) diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpBase.java b/hutool-http/src/main/java/cn/hutool/http/HttpBase.java index 743d51a23..aaa280763 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpBase.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpBase.java @@ -2,6 +2,7 @@ package cn.hutool.http; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.io.resource.Resource; import cn.hutool.core.map.CaseInsensitiveMap; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.CharsetUtil; @@ -53,7 +54,7 @@ public abstract class HttpBase { /** * 存储主体 */ - protected byte[] bodyBytes; + protected Resource body; // ---------------------------------------------------------------- Headers start @@ -303,7 +304,7 @@ public abstract class HttpBase { * @return byte[] */ public byte[] bodyBytes() { - return this.bodyBytes; + return this.body.readBytes(); } /** @@ -345,7 +346,7 @@ public abstract class HttpBase { @Override public String toString() { - StringBuilder sb = StrUtil.builder(); + final StringBuilder sb = StrUtil.builder(); sb.append("Request Headers: ").append(StrUtil.CRLF); for (Entry> entry : this.headers.entrySet()) { sb.append(" ").append( @@ -354,7 +355,7 @@ public abstract class HttpBase { } sb.append("Request Body: ").append(StrUtil.CRLF); - sb.append(" ").append(StrUtil.str(this.bodyBytes, this.charset)).append(StrUtil.CRLF); + sb.append(" ").append(StrUtil.str(this.body.readBytes(), this.charset)).append(StrUtil.CRLF); return sb.toString(); } 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 ef9694c14..acd397f7b 100755 --- a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java @@ -16,10 +16,10 @@ 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.body.ResourceBody; import cn.hutool.http.cookie.GlobalCookieManager; import javax.net.ssl.HostnameVerifier; @@ -499,7 +499,7 @@ public class HttpRequest extends HttpBase { } // 停用body - this.bodyBytes = null; + this.body = null; if (value instanceof File) { // 文件上传 @@ -752,8 +752,22 @@ public class HttpRequest extends HttpBase { * @return this */ public HttpRequest body(byte[] bodyBytes) { - if (null != bodyBytes) { - this.bodyBytes = bodyBytes; + if (ArrayUtil.isNotEmpty(bodyBytes)) { + return body(new BytesResource(bodyBytes)); + } + return this; + } + + /** + * 设置主体字节码
+ * 需在此方法调用前使用charset方法设置编码,否则使用默认编码UTF-8 + * + * @param resource 主体 + * @return this + */ + public HttpRequest body(Resource resource) { + if (null != resource) { + this.body = resource; } return this; } @@ -1225,8 +1239,8 @@ public class HttpRequest extends HttpBase { } // 优先使用body形式的参数,不存在使用form - if (ArrayUtil.isNotEmpty(this.bodyBytes)) { - query.parse(StrUtil.str(this.bodyBytes, this.charset), this.charset); + if (null != this.body) { + query.parse(StrUtil.str(this.body.readBytes(), this.charset), this.charset); } else { query.addAll(this.form); } @@ -1319,8 +1333,8 @@ public class HttpRequest extends HttpBase { // Write的时候会优先使用body中的内容,write时自动关闭OutputStream RequestBody body; - if (ArrayUtil.isNotEmpty(this.bodyBytes)) { - body = BytesBody.create(this.bodyBytes); + if (null != this.body) { + body = ResourceBody.create(this.body); } else { body = FormUrlEncodedBody.create(this.form, this.charset); } diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java b/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java index e11be2753..6607bb157 100755 --- a/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpResponse.java @@ -6,6 +6,7 @@ import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.StreamProgress; +import cn.hutool.core.io.resource.BytesResource; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ReUtil; @@ -13,7 +14,6 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.URLUtil; import cn.hutool.http.cookie.GlobalCookieManager; -import java.io.ByteArrayInputStream; import java.io.Closeable; import java.io.EOFException; import java.io.File; @@ -222,7 +222,7 @@ public class HttpResponse extends HttpBase implements Closeable { * @since 4.1.4 */ public String getCookieValue(String name) { - HttpCookie cookie = getCookie(name); + final HttpCookie cookie = getCookie(name); return (null == cookie) ? null : cookie.getValue(); } // ---------------------------------------------------------------- Http Response Header end @@ -241,7 +241,7 @@ public class HttpResponse extends HttpBase implements Closeable { if (isAsync) { return this.in; } - return new ByteArrayInputStream(this.bodyBytes); + return this.body.getStream(); } /** @@ -253,7 +253,7 @@ public class HttpResponse extends HttpBase implements Closeable { @Override public byte[] bodyBytes() { sync(); - return this.bodyBytes; + return this.body.readBytes(); } /** @@ -266,7 +266,7 @@ public class HttpResponse extends HttpBase implements Closeable { public HttpResponse body(byte[] bodyBytes) { sync(); if (null != bodyBytes) { - this.bodyBytes = bodyBytes; + this.body = new BytesResource(bodyBytes); } return this; } @@ -606,7 +606,7 @@ public class HttpResponse extends HttpBase implements Closeable { final long contentLength = contentLength(); final FastByteArrayOutputStream out = new FastByteArrayOutputStream((int) contentLength); copyBody(in, out, contentLength, null, this.config.ignoreEOFError); - this.bodyBytes = out.toByteArray(); + this.body = new BytesResource(out.toByteArray()); } /** diff --git a/hutool-http/src/main/java/cn/hutool/http/body/ResourceBody.java b/hutool-http/src/main/java/cn/hutool/http/body/ResourceBody.java new file mode 100644 index 000000000..af5b91ce6 --- /dev/null +++ b/hutool-http/src/main/java/cn/hutool/http/body/ResourceBody.java @@ -0,0 +1,42 @@ +package cn.hutool.http.body; + +import cn.hutool.core.io.resource.Resource; + +import java.io.OutputStream; + +/** + * {@link Resource}类型的Http request body,主要发送编码后的表单数据或rest body(如JSON或XML) + * + * @author looly + * @since 5.8.13 + */ +public class ResourceBody implements RequestBody { + + private final Resource resource; + + /** + * 创建 Http request body + * + * @param resource body内容,编码后 + * @return BytesBody + */ + public static ResourceBody create(Resource resource) { + return new ResourceBody(resource); + } + + /** + * 构造 + * + * @param resource Body内容,编码后 + */ + public ResourceBody(Resource resource) { + this.resource = resource; + } + + @Override + public void write(OutputStream out) { + if(null != this.resource){ + this.resource.writeTo(out); + } + } +} diff --git a/hutool-http/src/test/java/cn/hutool/http/RestTest.java b/hutool-http/src/test/java/cn/hutool/http/RestTest.java index 9ed57277b..dc93de788 100644 --- a/hutool-http/src/test/java/cn/hutool/http/RestTest.java +++ b/hutool-http/src/test/java/cn/hutool/http/RestTest.java @@ -1,5 +1,6 @@ package cn.hutool.http; +import cn.hutool.core.io.resource.StringResource; import cn.hutool.core.lang.Console; import cn.hutool.json.JSONUtil; import org.junit.Assert; @@ -10,7 +11,6 @@ import org.junit.Test; * Rest类型请求单元测试 * * @author looly - * */ public class RestTest { @@ -26,10 +26,10 @@ public class RestTest { @Test @Ignore public void postTest() { - HttpRequest request = HttpRequest.post("http://localhost:8090/rest/restTest/")// - .body(JSONUtil.createObj() + HttpRequest request = HttpRequest.post("http://localhost:8888/restTest/")// + .body(new StringResource(JSONUtil.createObj() .set("aaa", "aaaValue") - .set("键2", "值2").toString()); + .set("键2", "值2").toString())); Console.log(request.execute().body()); } @@ -59,17 +59,17 @@ public class RestTest { HttpRequest request = HttpRequest.get("https://ad.oceanengine.com/open_api/2/advertiser/info/")// // Charles代理 .setHttpProxy("localhost", 8888) - .header("Access-Token","") + .header("Access-Token", "") .body(JSONUtil.createObj() - .set("advertiser_ids", new Long[] {1690657248243790L}) - .set("fields", new String[] {"id", "name", "status"}).toString()); + .set("advertiser_ids", new Long[]{1690657248243790L}) + .set("fields", new String[]{"id", "name", "status"}).toString()); Console.log(request); Console.log(request.execute().body()); } @Test @Ignore - public void getTest(){ + public void getTest() { final HttpRequest request = HttpRequest.get("http://localhost:8888/restTest"); final HttpResponse execute = request.execute(); Console.log(execute.headers());