This commit is contained in:
Looly 2024-07-18 10:11:51 +08:00
parent 1e9afdd816
commit 88b3e484af
3 changed files with 52 additions and 5 deletions

View File

@ -14,6 +14,7 @@ package org.dromara.hutool.http.client.body;
import org.dromara.hutool.core.io.stream.FastByteArrayOutputStream; import org.dromara.hutool.core.io.stream.FastByteArrayOutputStream;
import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.text.StrUtil;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -32,23 +33,39 @@ public interface HttpBody {
void write(OutputStream out); void write(OutputStream out);
/** /**
* 获取Content-Type * 获取Content-Type<br>
* 根据实现不同Content-Type可能包含编码信息也可以不包含
* *
* @return Content-Type值 * @return Content-Type值
*/ */
String getContentType(); String getContentType();
/** /**
* 获取指定编码的Content-Type类似于application/json;charset=UTF-8 * 获取指定编码的Content-Type类似于application/json;charset=UTF-8<br>
* 如果{@link #getContentType()} 已经包含编码信息则编码信息一致直接返回否则替换为指定编码
*
* @param charset 编码 * @param charset 编码
* @return Content-Type * @return Content-Type
* @see #getContentType()
*/ */
default String getContentType(final Charset charset) { default String getContentType(final Charset charset) {
final String contentType = getContentType(); String contentType = getContentType();
if (null == contentType) { if (null == contentType) {
return null; return null;
} }
final String charsetName = charset.name();
if (StrUtil.endWithIgnoreCase(contentType, charsetName) || StrUtil.containsIgnoreCase(contentType, "boundary=")) {
// 已经包含编码信息且编码一致无需再次添加
// multipart无需添加charset
return contentType;
}
if (StrUtil.containsIgnoreCase(contentType, ";charset=")) {
// 已经包含编码信息但编码不一致需要替换
contentType = StrUtil.subBefore(contentType, ";charset=", true);
}
return contentType + ";charset=" + charset.name(); return contentType + ";charset=" + charset.name();
} }

View File

@ -84,6 +84,12 @@ public class MultipartBody extends FormBody<MultipartBody> {
return CONTENT_TYPE_MULTIPART_PREFIX + boundary; return CONTENT_TYPE_MULTIPART_PREFIX + boundary;
} }
@Override
public String getContentType(final Charset charset) {
// multipart的Content-Type头指定"Content-Type; boundary=XXXX"编码无效
return getContentType();
}
/** /**
* 写出Multiparty数据不关闭流 * 写出Multiparty数据不关闭流
* *

View File

@ -0,0 +1,24 @@
package org.dromara.hutool.http.client;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.http.meta.HeaderName;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Collection;
import java.util.Collections;
public class Issue3658Test {
@Test
public void name() {
// 请注意这里一定使用带form参数的get方法参数随便设什么都行url也随便
final Request request = Request.of("https://timor.tech/api/holiday/year/2020-02")
.form(Collections.singletonMap("11", "22"));
final Collection<String> collection = request.headers().get(HeaderName.CONTENT_TYPE.getValue());
final String s = CollUtil.get(collection, 0);
Assertions.assertEquals("application/x-www-form-urlencoded;charset=UTF-8", s);
}
}