HttpRequest#body增加支持Resource重载

This commit is contained in:
Looly 2023-03-03 20:25:27 +08:00
parent a25a707e3a
commit 0d11f82ee8
6 changed files with 85 additions and 27 deletions

View File

@ -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 】 PhoneUtil.isTel400800支持400-XXX-XXXX格式issue#2929@Github
* 【core 】 build(pom): 添加 Automatic-Module-Name属性pr#2926@Github * 【core 】 build(pom): 添加 Automatic-Module-Name属性pr#2926@Github
* 【core 】 根据JDK-8080225修改了部分新建文件输入流和文件输出流的创建方式pr#2930@Github * 【core 】 根据JDK-8080225修改了部分新建文件输入流和文件输出流的创建方式pr#2930@Github
* 【http 】 HttpRequest#body增加支持Resource重载issue#2901@Github
### 🐞Bug修复 ### 🐞Bug修复
* 【db 】 修复识别JDBC驱动时重复问题pr#940@Gitee * 【db 】 修复识别JDBC驱动时重复问题pr#940@Gitee

View File

@ -2,6 +2,7 @@ package cn.hutool.http;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.map.CaseInsensitiveMap; import cn.hutool.core.map.CaseInsensitiveMap;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.CharsetUtil;
@ -53,7 +54,7 @@ public abstract class HttpBase<T> {
/** /**
* 存储主体 * 存储主体
*/ */
protected byte[] bodyBytes; protected Resource body;
// ---------------------------------------------------------------- Headers start // ---------------------------------------------------------------- Headers start
@ -303,7 +304,7 @@ public abstract class HttpBase<T> {
* @return byte[] * @return byte[]
*/ */
public byte[] bodyBytes() { public byte[] bodyBytes() {
return this.bodyBytes; return this.body.readBytes();
} }
/** /**
@ -345,7 +346,7 @@ public abstract class HttpBase<T> {
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = StrUtil.builder(); final StringBuilder sb = StrUtil.builder();
sb.append("Request Headers: ").append(StrUtil.CRLF); sb.append("Request Headers: ").append(StrUtil.CRLF);
for (Entry<String, List<String>> entry : this.headers.entrySet()) { for (Entry<String, List<String>> entry : this.headers.entrySet()) {
sb.append(" ").append( sb.append(" ").append(
@ -354,7 +355,7 @@ public abstract class HttpBase<T> {
} }
sb.append("Request Body: ").append(StrUtil.CRLF); 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(); return sb.toString();
} }

View File

@ -16,10 +16,10 @@ import cn.hutool.core.net.url.UrlQuery;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.http.body.BytesBody;
import cn.hutool.http.body.FormUrlEncodedBody; import cn.hutool.http.body.FormUrlEncodedBody;
import cn.hutool.http.body.MultipartBody; import cn.hutool.http.body.MultipartBody;
import cn.hutool.http.body.RequestBody; import cn.hutool.http.body.RequestBody;
import cn.hutool.http.body.ResourceBody;
import cn.hutool.http.cookie.GlobalCookieManager; import cn.hutool.http.cookie.GlobalCookieManager;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
@ -499,7 +499,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
} }
// 停用body // 停用body
this.bodyBytes = null; this.body = null;
if (value instanceof File) { if (value instanceof File) {
// 文件上传 // 文件上传
@ -752,8 +752,22 @@ public class HttpRequest extends HttpBase<HttpRequest> {
* @return this * @return this
*/ */
public HttpRequest body(byte[] bodyBytes) { public HttpRequest body(byte[] bodyBytes) {
if (null != bodyBytes) { if (ArrayUtil.isNotEmpty(bodyBytes)) {
this.bodyBytes = bodyBytes; return body(new BytesResource(bodyBytes));
}
return this;
}
/**
* 设置主体字节码<br>
* 需在此方法调用前使用charset方法设置编码否则使用默认编码UTF-8
*
* @param resource 主体
* @return this
*/
public HttpRequest body(Resource resource) {
if (null != resource) {
this.body = resource;
} }
return this; return this;
} }
@ -1225,8 +1239,8 @@ public class HttpRequest extends HttpBase<HttpRequest> {
} }
// 优先使用body形式的参数不存在使用form // 优先使用body形式的参数不存在使用form
if (ArrayUtil.isNotEmpty(this.bodyBytes)) { if (null != this.body) {
query.parse(StrUtil.str(this.bodyBytes, this.charset), this.charset); query.parse(StrUtil.str(this.body.readBytes(), this.charset), this.charset);
} else { } else {
query.addAll(this.form); query.addAll(this.form);
} }
@ -1319,8 +1333,8 @@ public class HttpRequest extends HttpBase<HttpRequest> {
// Write的时候会优先使用body中的内容write时自动关闭OutputStream // Write的时候会优先使用body中的内容write时自动关闭OutputStream
RequestBody body; RequestBody body;
if (ArrayUtil.isNotEmpty(this.bodyBytes)) { if (null != this.body) {
body = BytesBody.create(this.bodyBytes); body = ResourceBody.create(this.body);
} else { } else {
body = FormUrlEncodedBody.create(this.form, this.charset); body = FormUrlEncodedBody.create(this.form, this.charset);
} }

View File

@ -6,6 +6,7 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.StreamProgress; import cn.hutool.core.io.StreamProgress;
import cn.hutool.core.io.resource.BytesResource;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ReUtil; 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.core.util.URLUtil;
import cn.hutool.http.cookie.GlobalCookieManager; import cn.hutool.http.cookie.GlobalCookieManager;
import java.io.ByteArrayInputStream;
import java.io.Closeable; import java.io.Closeable;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
@ -222,7 +222,7 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
* @since 4.1.4 * @since 4.1.4
*/ */
public String getCookieValue(String name) { public String getCookieValue(String name) {
HttpCookie cookie = getCookie(name); final HttpCookie cookie = getCookie(name);
return (null == cookie) ? null : cookie.getValue(); return (null == cookie) ? null : cookie.getValue();
} }
// ---------------------------------------------------------------- Http Response Header end // ---------------------------------------------------------------- Http Response Header end
@ -241,7 +241,7 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
if (isAsync) { if (isAsync) {
return this.in; return this.in;
} }
return new ByteArrayInputStream(this.bodyBytes); return this.body.getStream();
} }
/** /**
@ -253,7 +253,7 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
@Override @Override
public byte[] bodyBytes() { public byte[] bodyBytes() {
sync(); sync();
return this.bodyBytes; return this.body.readBytes();
} }
/** /**
@ -266,7 +266,7 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
public HttpResponse body(byte[] bodyBytes) { public HttpResponse body(byte[] bodyBytes) {
sync(); sync();
if (null != bodyBytes) { if (null != bodyBytes) {
this.bodyBytes = bodyBytes; this.body = new BytesResource(bodyBytes);
} }
return this; return this;
} }
@ -606,7 +606,7 @@ public class HttpResponse extends HttpBase<HttpResponse> implements Closeable {
final long contentLength = contentLength(); final long contentLength = contentLength();
final FastByteArrayOutputStream out = new FastByteArrayOutputStream((int) contentLength); final FastByteArrayOutputStream out = new FastByteArrayOutputStream((int) contentLength);
copyBody(in, out, contentLength, null, this.config.ignoreEOFError); copyBody(in, out, contentLength, null, this.config.ignoreEOFError);
this.bodyBytes = out.toByteArray(); this.body = new BytesResource(out.toByteArray());
} }
/** /**

View File

@ -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);
}
}
}

View File

@ -1,5 +1,6 @@
package cn.hutool.http; package cn.hutool.http;
import cn.hutool.core.io.resource.StringResource;
import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Console;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import org.junit.Assert; import org.junit.Assert;
@ -10,7 +11,6 @@ import org.junit.Test;
* Rest类型请求单元测试 * Rest类型请求单元测试
* *
* @author looly * @author looly
*
*/ */
public class RestTest { public class RestTest {
@ -26,10 +26,10 @@ public class RestTest {
@Test @Test
@Ignore @Ignore
public void postTest() { public void postTest() {
HttpRequest request = HttpRequest.post("http://localhost:8090/rest/restTest/")// HttpRequest request = HttpRequest.post("http://localhost:8888/restTest/")//
.body(JSONUtil.createObj() .body(new StringResource(JSONUtil.createObj()
.set("aaa", "aaaValue") .set("aaa", "aaaValue")
.set("键2", "值2").toString()); .set("键2", "值2").toString()));
Console.log(request.execute().body()); 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/")// HttpRequest request = HttpRequest.get("https://ad.oceanengine.com/open_api/2/advertiser/info/")//
// Charles代理 // Charles代理
.setHttpProxy("localhost", 8888) .setHttpProxy("localhost", 8888)
.header("Access-Token","") .header("Access-Token", "")
.body(JSONUtil.createObj() .body(JSONUtil.createObj()
.set("advertiser_ids", new Long[] {1690657248243790L}) .set("advertiser_ids", new Long[]{1690657248243790L})
.set("fields", new String[] {"id", "name", "status"}).toString()); .set("fields", new String[]{"id", "name", "status"}).toString());
Console.log(request); Console.log(request);
Console.log(request.execute().body()); Console.log(request.execute().body());
} }
@Test @Test
@Ignore @Ignore
public void getTest(){ public void getTest() {
final HttpRequest request = HttpRequest.get("http://localhost:8888/restTest"); final HttpRequest request = HttpRequest.get("http://localhost:8888/restTest");
final HttpResponse execute = request.execute(); final HttpResponse execute = request.execute();
Console.log(execute.headers()); Console.log(execute.headers());