diff --git a/CHANGELOG.md b/CHANGELOG.md index f78869409..2fb1977d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ * 【core 】 AsyncUtil.waitAny增加返回值(pr#473@Gitee) * 【core 】 Calculator.compare改为private(issue#1982@Github) * 【core 】 NumberUtil增加isOdd、isEven方法(pr#474@Gitee) +* 【http 】 增加HttpGlobalConfig.setBoundary,删除MultipartBody.BOUNDARY和getContentType(issue#I4KSLY@Gitee) * ### 🐞Bug修复 * 【core 】 修复FileResource构造fileName参数无效问题(issue#1942@Github) diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpGlobalConfig.java b/hutool-http/src/main/java/cn/hutool/http/HttpGlobalConfig.java index d45d23593..ae76d932d 100755 --- a/hutool-http/src/main/java/cn/hutool/http/HttpGlobalConfig.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpGlobalConfig.java @@ -1,6 +1,7 @@ package cn.hutool.http; import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.http.cookie.GlobalCookieManager; @@ -21,6 +22,7 @@ public class HttpGlobalConfig implements Serializable { protected static int timeout = -1; private static boolean isAllowPatch = false; + private static String boundary = "--------------------Hutool_" + RandomUtil.randomString(16); /** * 获取全局默认的超时时长 @@ -40,6 +42,26 @@ public class HttpGlobalConfig implements Serializable { timeout = customTimeout; } + /** + * 获取全局默认的Multipart边界 + * + * @return 全局默认的Multipart边界 + * @since 5.7.17 + */ + public static String getBoundary() { + return boundary; + } + + /** + * 设置默认的Multipart边界 + * + * @param customBoundary 自定义Multipart边界 + * @since 5.7.17 + */ + synchronized public static void setBoundary(String customBoundary) { + boundary = customBoundary; + } + /** * 获取Cookie管理器,用于自定义Cookie管理 * 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 12a14e699..67a43e027 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java @@ -1228,9 +1228,10 @@ public class HttpRequest extends HttpBase { * @throws IOException IO异常 */ private void sendMultipart() throws IOException { + final MultipartBody multipartBody = MultipartBody.create(this.form, this.charset); //设置表单类型为Multipart(文件上传) - this.httpConnection.header(Header.CONTENT_TYPE, MultipartBody.getContentType(), true); - MultipartBody.create(this.form, this.charset).writeClose(this.httpConnection.getOutputStream()); + this.httpConnection.header(Header.CONTENT_TYPE, multipartBody.getContentType(), true); + multipartBody.writeClose(this.httpConnection.getOutputStream()); } /** diff --git a/hutool-http/src/main/java/cn/hutool/http/MultipartOutputStream.java b/hutool-http/src/main/java/cn/hutool/http/MultipartOutputStream.java index 5ca620ad1..c944f3792 100644 --- a/hutool-http/src/main/java/cn/hutool/http/MultipartOutputStream.java +++ b/hutool-http/src/main/java/cn/hutool/http/MultipartOutputStream.java @@ -7,7 +7,6 @@ import cn.hutool.core.io.resource.MultiResource; import cn.hutool.core.io.resource.Resource; import cn.hutool.core.io.resource.StringResource; import cn.hutool.core.util.StrUtil; -import cn.hutool.http.body.MultipartBody; import java.io.IOException; import java.io.OutputStream; @@ -17,13 +16,11 @@ import java.nio.charset.Charset; * Multipart/form-data输出流封装
* 遵循RFC2388规范 * - * @since 5.7.17 * @author looly + * @since 5.7.17 */ public class MultipartOutputStream extends OutputStream { - private static final String BOUNDARY = MultipartBody.BOUNDARY; - private static final String BOUNDARY_END = StrUtil.format("--{}--\r\n", BOUNDARY); private static final String CONTENT_DISPOSITION_TEMPLATE = "Content-Disposition: form-data; name=\"{}\"\r\n"; private static final String CONTENT_DISPOSITION_FILE_TEMPLATE = "Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n"; @@ -31,17 +28,32 @@ public class MultipartOutputStream extends OutputStream { private final OutputStream out; private final Charset charset; + private final String boundary; + private boolean isFinish; /** - * 构造 + * 构造,使用全局默认的边界字符串 * * @param out HTTP写出流 * @param charset 编码 */ public MultipartOutputStream(OutputStream out, Charset charset) { + this(out, charset, HttpGlobalConfig.getBoundary()); + } + + /** + * 构造 + * + * @param out HTTP写出流 + * @param charset 编码 + * @param boundary 边界符 + * @since 5.7.17 + */ + public MultipartOutputStream(OutputStream out, Charset charset, String boundary) { this.out = out; this.charset = charset; + this.boundary = boundary; } /** @@ -101,8 +113,8 @@ public class MultipartOutputStream extends OutputStream { * @throws IORuntimeException IO异常 */ public void finish() throws IORuntimeException { - if(false == isFinish){ - write(BOUNDARY_END); + if (false == isFinish) { + write(StrUtil.format("--{}--\r\n", boundary)); this.isFinish = true; } } @@ -139,7 +151,7 @@ public class MultipartOutputStream extends OutputStream { // Content-Type: 类型[换行] write(StrUtil.format(CONTENT_TYPE_FILE_TEMPLATE, contentType)); } - } else if(StrUtil.isNotEmpty(fileName)){ + } else if (StrUtil.isNotEmpty(fileName)) { // 根据name的扩展名指定互联网媒体类型,默认二进制流数据 write(StrUtil.format(CONTENT_TYPE_FILE_TEMPLATE, HttpUtil.getMimeType(fileName, ContentType.OCTET_STREAM.getValue()))); @@ -156,9 +168,9 @@ public class MultipartOutputStream extends OutputStream { * --分隔符(boundary)[换行] * */ - private void beginPart(){ + private void beginPart() { // --分隔符(boundary)[换行] - write("--", BOUNDARY, StrUtil.CRLF); + write("--", boundary, StrUtil.CRLF); } /** diff --git a/hutool-http/src/main/java/cn/hutool/http/body/MultipartBody.java b/hutool-http/src/main/java/cn/hutool/http/body/MultipartBody.java index dbf955363..37077832f 100644 --- a/hutool-http/src/main/java/cn/hutool/http/body/MultipartBody.java +++ b/hutool-http/src/main/java/cn/hutool/http/body/MultipartBody.java @@ -2,8 +2,8 @@ package cn.hutool.http.body; import cn.hutool.core.io.IoUtil; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.RandomUtil; import cn.hutool.http.ContentType; +import cn.hutool.http.HttpGlobalConfig; import cn.hutool.http.MultipartOutputStream; import java.io.ByteArrayOutputStream; @@ -20,7 +20,6 @@ import java.util.Map; */ public class MultipartBody implements RequestBody { - public static final String BOUNDARY = "--------------------Hutool_" + RandomUtil.randomString(16); private static final String CONTENT_TYPE_MULTIPART_PREFIX = ContentType.MULTIPART.getValue() + "; boundary="; /** @@ -31,6 +30,10 @@ public class MultipartBody implements RequestBody { * 编码 */ private final Charset charset; + /** + * 边界 + */ + private final String boundary = HttpGlobalConfig.getBoundary(); /** * 根据已有表单内容,构建MultipartBody @@ -48,8 +51,8 @@ public class MultipartBody implements RequestBody { * * @return Multipart的Content-Type类型 */ - public static String getContentType() { - return CONTENT_TYPE_MULTIPART_PREFIX + BOUNDARY; + public String getContentType() { + return CONTENT_TYPE_MULTIPART_PREFIX + boundary; } /** @@ -70,7 +73,7 @@ public class MultipartBody implements RequestBody { */ @Override public void write(OutputStream out) { - final MultipartOutputStream stream = new MultipartOutputStream(out, this.charset); + final MultipartOutputStream stream = new MultipartOutputStream(out, this.charset, this.boundary); if (MapUtil.isNotEmpty(this.form)) { this.form.forEach(stream::write); }