add config

This commit is contained in:
Looly 2024-09-05 20:39:40 +08:00
parent 6ae4169951
commit 9b1ad25864
6 changed files with 63 additions and 25 deletions

View File

@ -56,6 +56,10 @@ public class ClientConfig {
* 代理 * 代理
*/ */
private HttpProxy proxy; private HttpProxy proxy;
/**
* 是否遇到响应状态码3xx时自动重定向请求
*/
private boolean followRedirects;
/** /**
* 构造 * 构造
@ -152,7 +156,7 @@ public class ClientConfig {
* *
* @return this * @return this
*/ */
public ClientConfig enableSSLVerify(){ public ClientConfig enableSSLVerify() {
return setSSLInfo(SSLInfo.DEFAULT); return setSSLInfo(SSLInfo.DEFAULT);
} }
@ -204,4 +208,26 @@ public class ClientConfig {
this.proxy = proxy; this.proxy = proxy;
return this; return this;
} }
/**
* 是否遇到响应状态码3xx时自动重定向请求<br>
* 注意当打开客户端级别的自动重定向{@link Request#maxRedirectCount()}无效
*
* @return 是否遇到响应状态码3xx时自动重定向请求
*/
public boolean isFollowRedirects() {
return followRedirects;
}
/**
* 设置是否遇到响应状态码3xx时自动重定向请求<br>
* 注意当打开客户端级别的自动重定向{@link Request#maxRedirectCount()}无效
*
* @param followRedirects 是否遇到响应状态码3xx时自动重定向请求
* @return this
*/
public ClientConfig setFollowRedirects(final boolean followRedirects) {
this.followRedirects = followRedirects;
return this;
}
} }

View File

@ -293,6 +293,7 @@ public class Request implements HeaderOperation<Request> {
// endregion // endregion
// region body get // region body get
/** /**
* 获取请求体 * 获取请求体
* *
@ -343,6 +344,7 @@ public class Request implements HeaderOperation<Request> {
// endregion // endregion
// region body set // region body set
/** /**
* 添加请求表单内容 * 添加请求表单内容
* *
@ -386,7 +388,7 @@ public class Request implements HeaderOperation<Request> {
if (StrUtil.isBlank(header(HeaderName.CONTENT_TYPE))) { if (StrUtil.isBlank(header(HeaderName.CONTENT_TYPE))) {
final String contentType = body.contentType(charset()); final String contentType = body.contentType(charset());
// 如果用户自定义的Header为null不调用防止实现类中可能的空指针问题 // 如果用户自定义的Header为null不调用防止实现类中可能的空指针问题
if(null != contentType){ if (null != contentType) {
header(HeaderName.CONTENT_TYPE, contentType, true); header(HeaderName.CONTENT_TYPE, contentType, true);
} }
} }
@ -396,7 +398,8 @@ public class Request implements HeaderOperation<Request> {
// endregion // endregion
/** /**
* 获取最大重定向请求次数 * 获取最大重定向请求次数<br>
* 注意{@link ClientConfig#isFollowRedirects()}{@code true}此参数无效
* *
* @return 最大重定向请求次数 * @return 最大重定向请求次数
*/ */
@ -406,7 +409,8 @@ public class Request implements HeaderOperation<Request> {
/** /**
* 设置最大重定向次数<br> * 设置最大重定向次数<br>
* 如果次数小于1则表示不重定向大于等于1表示打开重定向 * 如果次数小于1则表示不重定向大于等于1表示打开重定向<br>
* 注意{@link ClientConfig#isFollowRedirects()}{@code true}此参数无效
* *
* @param maxRedirectCount 最大重定向次数 * @param maxRedirectCount 最大重定向次数
* @return this * @return this
@ -477,13 +481,14 @@ public class Request implements HeaderOperation<Request> {
/** /**
* 检查form表单中的对象是否为Multipart对象 * 检查form表单中的对象是否为Multipart对象
*
* @param value 对象 * @param value 对象
* @return 是否为Multipart对象 * @return 是否为Multipart对象
*/ */
private static boolean hasMultipartValue(final Object value){ private static boolean hasMultipartValue(final Object value) {
if(value instanceof Iterable){ if (value instanceof Iterable) {
for (final Object subValue : (Iterable<?>) value) { for (final Object subValue : (Iterable<?>) value) {
if(hasMultipartValue(subValue)){ if (hasMultipartValue(subValue)) {
return true; return true;
} }
} }

View File

@ -25,10 +25,7 @@ import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder; import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHeader;
import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.IoUtil;
@ -118,7 +115,7 @@ public class HttpClient4Engine extends AbstractClientEngine {
if (null != sslInfo) { if (null != sslInfo) {
clientBuilder.setSSLSocketFactory(buildSocketFactory(sslInfo)); clientBuilder.setSSLSocketFactory(buildSocketFactory(sslInfo));
} }
if(config.isDisableCache()){ if (config.isDisableCache()) {
clientBuilder.disableAuthCaching(); clientBuilder.disableAuthCaching();
} }
@ -128,8 +125,12 @@ public class HttpClient4Engine extends AbstractClientEngine {
// 设置默认头信息 // 设置默认头信息
clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers())); clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers()));
// 默认关闭自动重定向 // 重定向
clientBuilder.disableRedirectHandling(); if (config.isFollowRedirects()) {
clientBuilder.setRedirectStrategy(LaxRedirectStrategy.INSTANCE);
} else {
clientBuilder.disableRedirectHandling();
}
// 设置代理 // 设置代理
setProxy(clientBuilder, config); setProxy(clientBuilder, config);
@ -156,7 +157,7 @@ public class HttpClient4Engine extends AbstractClientEngine {
// 填充自定义消息体 // 填充自定义消息体
final HttpBody body = message.handledBody(); final HttpBody body = message.handledBody();
if(null != body){ if (null != body) {
requestBuilder.setEntity(new HttpClient4BodyEntity( requestBuilder.setEntity(new HttpClient4BodyEntity(
// 用户自定义的内容类型 // 用户自定义的内容类型
message.header(HeaderName.CONTENT_TYPE), message.header(HeaderName.CONTENT_TYPE),
@ -194,6 +195,7 @@ public class HttpClient4Engine extends AbstractClientEngine {
/** /**
* 构建连接池管理器 * 构建连接池管理器
*
* @param config 配置 * @param config 配置
* @return PoolingHttpClientConnectionManager * @return PoolingHttpClientConnectionManager
*/ */
@ -201,7 +203,7 @@ public class HttpClient4Engine extends AbstractClientEngine {
final PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(); final PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();
// 连接池配置 // 连接池配置
if(config instanceof HttpClientConfig){ if (config instanceof HttpClientConfig) {
final HttpClientConfig httpClientConfig = (HttpClientConfig) config; final HttpClientConfig httpClientConfig = (HttpClientConfig) config;
manager.setMaxTotal(httpClientConfig.getMaxTotal()); manager.setMaxTotal(httpClientConfig.getMaxTotal());
manager.setDefaultMaxPerRoute(httpClientConfig.getMaxPerRoute()); manager.setDefaultMaxPerRoute(httpClientConfig.getMaxPerRoute());

View File

@ -21,6 +21,7 @@ import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
import org.apache.hc.client5.http.config.ConnectionConfig; import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider; import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
@ -119,15 +120,19 @@ public class HttpClient5Engine extends AbstractClientEngine {
final ClientConfig config = ObjUtil.defaultIfNull(this.config, HttpClientConfig::of); final ClientConfig config = ObjUtil.defaultIfNull(this.config, HttpClientConfig::of);
clientBuilder.setConnectionManager(buildConnectionManager(config)); clientBuilder.setConnectionManager(buildConnectionManager(config));
clientBuilder.setDefaultRequestConfig(buildRequestConfig(config)); clientBuilder.setDefaultRequestConfig(buildRequestConfig(config));
if(config.isDisableCache()){ if (config.isDisableCache()) {
clientBuilder.disableAuthCaching(); clientBuilder.disableAuthCaching();
} }
// 设置默认头信息 // 设置默认头信息
clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers())); clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers()));
// 默认关闭自动重定向 // 重定向
clientBuilder.disableRedirectHandling(); if (config.isFollowRedirects()) {
clientBuilder.setRedirectStrategy(DefaultRedirectStrategy.INSTANCE);
} else {
clientBuilder.disableRedirectHandling();
}
// 设置代理 // 设置代理
setProxy(clientBuilder, config); setProxy(clientBuilder, config);
@ -153,7 +158,7 @@ public class HttpClient5Engine extends AbstractClientEngine {
// 填充自定义消息体 // 填充自定义消息体
final HttpBody body = message.handledBody(); final HttpBody body = message.handledBody();
if(null != body){ if (null != body) {
request.setEntity(new HttpClient5BodyEntity( request.setEntity(new HttpClient5BodyEntity(
// 用户自定义的内容类型 // 用户自定义的内容类型
message.header(HeaderName.CONTENT_TYPE), message.header(HeaderName.CONTENT_TYPE),
@ -202,7 +207,7 @@ public class HttpClient5Engine extends AbstractClientEngine {
} }
// 连接池配置 // 连接池配置
if(config instanceof HttpClientConfig){ if (config instanceof HttpClientConfig) {
final HttpClientConfig httpClientConfig = (HttpClientConfig) config; final HttpClientConfig httpClientConfig = (HttpClientConfig) config;
final int maxTotal = httpClientConfig.getMaxTotal(); final int maxTotal = httpClientConfig.getMaxTotal();
final int maxPerRoute = httpClientConfig.getMaxPerRoute(); final int maxPerRoute = httpClientConfig.getMaxPerRoute();

View File

@ -129,8 +129,8 @@ public class JdkClientEngine extends AbstractClientEngine {
.setReadTimeout(config.getReadTimeout()) .setReadTimeout(config.getReadTimeout())
.setMethod(message.method())// .setMethod(message.method())//
.setSSLInfo(config.getSslInfo()) .setSSLInfo(config.getSslInfo())
// 关闭JDK自动转发采用手动转发方式 // 如果客户端设置自动重定向则Request中maxRedirectCount无效
.setInstanceFollowRedirects(false) .setInstanceFollowRedirects(config.isFollowRedirects())
.setDisableCache(config.isDisableCache()) .setDisableCache(config.isDisableCache())
// 覆盖默认Header // 覆盖默认Header
.header(message.headers(), true); .header(message.headers(), true);

View File

@ -129,8 +129,8 @@ public class OkHttpEngine extends AbstractClientEngine {
// 设置代理 // 设置代理
setProxy(builder, config); setProxy(builder, config);
// 默认关闭自动跳转 // 重定向
builder.followRedirects(false); builder.followRedirects(config.isFollowRedirects());
this.client = builder.build(); this.client = builder.build();
} }