This commit is contained in:
Looly 2024-08-08 20:43:45 +08:00
parent cf5c9793ea
commit 52cf8fdc71
9 changed files with 70 additions and 17 deletions

View File

@ -380,7 +380,7 @@ public class Request implements HeaderOperation<Request> {
// 根据内容赋值默认Content-Type // 根据内容赋值默认Content-Type
if (StrUtil.isBlank(header(HeaderName.CONTENT_TYPE))) { if (StrUtil.isBlank(header(HeaderName.CONTENT_TYPE))) {
header(HeaderName.CONTENT_TYPE, body.getContentType(charset()), true); header(HeaderName.CONTENT_TYPE, body.contentType(charset()), true);
} }
return this; return this;

View File

@ -38,18 +38,27 @@ public interface HttpBody {
* *
* @return Content-Type值 * @return Content-Type值
*/ */
String getContentType(); String contentType();
/**
* 获取写出字节长度未知为-1
*
* @return 长度
*/
default long contentLength() {
return -1;
}
/** /**
* 获取指定编码的Content-Type类似于application/json;charset=UTF-8<br> * 获取指定编码的Content-Type类似于application/json;charset=UTF-8<br>
* 如果{@link #getContentType()} 已经包含编码信息则编码信息一致直接返回否则替换为指定编码 * 如果{@link #contentType()} 已经包含编码信息则编码信息一致直接返回否则替换为指定编码
* *
* @param charset 编码 * @param charset 编码
* @return Content-Type * @return Content-Type
* @see #getContentType() * @see #contentType()
*/ */
default String getContentType(final Charset charset) { default String contentType(final Charset charset) {
String contentType = getContentType(); String contentType = contentType();
if (null == contentType) { if (null == contentType) {
return null; return null;
} }

View File

@ -80,14 +80,14 @@ public class MultipartBody extends FormBody<MultipartBody> {
* @return Multipart的Content-Type类型 * @return Multipart的Content-Type类型
*/ */
@Override @Override
public String getContentType() { public String contentType() {
return CONTENT_TYPE_MULTIPART_PREFIX + boundary; return CONTENT_TYPE_MULTIPART_PREFIX + boundary;
} }
@Override @Override
public String getContentType(final Charset charset) { public String contentType(final Charset charset) {
// multipart的Content-Type头指定"Content-Type; boundary=XXXX"编码无效 // multipart的Content-Type头指定"Content-Type; boundary=XXXX"编码无效
return getContentType(); return contentType();
} }
/** /**

View File

@ -67,7 +67,12 @@ public class ResourceBody implements HttpBody {
} }
@Override @Override
public String getContentType() { public String contentType() {
return this.resource.getContentType(); return this.resource.getContentType();
} }
@Override
public long contentLength() {
return resource.size();
}
} }

View File

@ -54,10 +54,15 @@ public class ResponseBody implements HttpBody, Closeable {
} }
@Override @Override
public String getContentType() { public String contentType() {
return response.header(HeaderName.CONTENT_TYPE); return response.header(HeaderName.CONTENT_TYPE);
} }
@Override
public long contentLength() {
return response.contentLength();
}
@Override @Override
public InputStream getStream() { public InputStream getStream() {
return this.bodyStream; return this.bodyStream;

View File

@ -29,6 +29,8 @@ import java.util.Map;
*/ */
public class UrlEncodedFormBody extends FormBody<UrlEncodedFormBody> { public class UrlEncodedFormBody extends FormBody<UrlEncodedFormBody> {
private byte[] content;
/** /**
* 创建 Http request body * 创建 Http request body
* *
@ -51,13 +53,38 @@ public class UrlEncodedFormBody extends FormBody<UrlEncodedFormBody> {
} }
@Override @Override
public void write(final OutputStream out) { public UrlEncodedFormBody form(final String name, final Object value) {
final byte[] bytes = ByteUtil.toBytes(UrlQuery.of(form, UrlQuery.EncodeMode.FORM_URL_ENCODED).build(charset), charset); // 有新键值对加入时清空生成的字节
IoUtil.write(out, false, bytes); if(null != this.content){
this.content = null;
}
return super.form(name, value);
} }
@Override @Override
public String getContentType() { public void write(final OutputStream out) {
IoUtil.write(out, getGeneratedBytes());
}
@Override
public String contentType() {
return ContentType.FORM_URLENCODED.toString(charset); return ContentType.FORM_URLENCODED.toString(charset);
} }
@Override
public long contentLength() {
return getGeneratedBytes().length;
}
/**
* 获取生成的字节数组
*
* @return 生成的字节数组
*/
private byte[] getGeneratedBytes() {
if (null == this.content) {
this.content = ByteUtil.toBytes(UrlQuery.of(form, UrlQuery.EncodeMode.FORM_URL_ENCODED).build(charset), charset);
}
return this.content;
}
} }

View File

@ -69,6 +69,6 @@ public class HttpClient4BodyEntity extends AbstractHttpEntity {
@Override @Override
public long getContentLength() { public long getContentLength() {
return -1; return body.contentLength();
} }
} }

View File

@ -66,6 +66,6 @@ public class HttpClient5BodyEntity extends AbstractHttpEntity {
@Override @Override
public long getContentLength() { public long getContentLength() {
return -1; return body.contentLength();
} }
} }

View File

@ -16,6 +16,8 @@ import org.dromara.hutool.http.client.body.HttpBody;
import okhttp3.MediaType; import okhttp3.MediaType;
import okio.BufferedSink; import okio.BufferedSink;
import java.io.IOException;
/** /**
* OkHttp的请求体实现通过{@link HttpBody}转换实现 * OkHttp的请求体实现通过{@link HttpBody}转换实现
* *
@ -39,6 +41,11 @@ public class OkHttpRequestBody extends okhttp3.RequestBody {
return null; return null;
} }
@Override
public long contentLength() throws IOException {
return this.body.contentLength();
}
@Override @Override
public void writeTo(final BufferedSink bufferedSink) { public void writeTo(final BufferedSink bufferedSink) {
body.writeClose(bufferedSink.outputStream()); body.writeClose(bufferedSink.outputStream());