From 9b1ad2586471ba7c86df812b98f1a0518f7a5e6f Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 5 Sep 2024 20:39:40 +0800 Subject: [PATCH] add config --- .../hutool/http/client/ClientConfig.java | 28 ++++++++++++++++++- .../dromara/hutool/http/client/Request.java | 17 +++++++---- .../engine/httpclient4/HttpClient4Engine.java | 20 +++++++------ .../engine/httpclient5/HttpClient5Engine.java | 15 ++++++---- .../client/engine/jdk/JdkClientEngine.java | 4 +-- .../client/engine/okhttp/OkHttpEngine.java | 4 +-- 6 files changed, 63 insertions(+), 25 deletions(-) diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/ClientConfig.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/ClientConfig.java index da08592ec..6f2e8e99f 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/ClientConfig.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/ClientConfig.java @@ -56,6 +56,10 @@ public class ClientConfig { * 代理 */ private HttpProxy proxy; + /** + * 是否遇到响应状态码3xx时自动重定向请求 + */ + private boolean followRedirects; /** * 构造 @@ -152,7 +156,7 @@ public class ClientConfig { * * @return this */ - public ClientConfig enableSSLVerify(){ + public ClientConfig enableSSLVerify() { return setSSLInfo(SSLInfo.DEFAULT); } @@ -204,4 +208,26 @@ public class ClientConfig { this.proxy = proxy; return this; } + + /** + * 是否遇到响应状态码3xx时自动重定向请求
+ * 注意:当打开客户端级别的自动重定向,则{@link Request#maxRedirectCount()}无效 + * + * @return 是否遇到响应状态码3xx时自动重定向请求 + */ + public boolean isFollowRedirects() { + return followRedirects; + } + + /** + * 设置是否遇到响应状态码3xx时自动重定向请求
+ * 注意:当打开客户端级别的自动重定向,则{@link Request#maxRedirectCount()}无效 + * + * @param followRedirects 是否遇到响应状态码3xx时自动重定向请求 + * @return this + */ + public ClientConfig setFollowRedirects(final boolean followRedirects) { + this.followRedirects = followRedirects; + return this; + } } diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/Request.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/Request.java index 420e21d6d..2b48866cc 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/Request.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/Request.java @@ -293,6 +293,7 @@ public class Request implements HeaderOperation { // endregion // region body get + /** * 获取请求体 * @@ -343,6 +344,7 @@ public class Request implements HeaderOperation { // endregion // region body set + /** * 添加请求表单内容 * @@ -386,7 +388,7 @@ public class Request implements HeaderOperation { if (StrUtil.isBlank(header(HeaderName.CONTENT_TYPE))) { final String contentType = body.contentType(charset()); // 如果用户自定义的Header为null,不调用,防止实现类中可能的空指针问题 - if(null != contentType){ + if (null != contentType) { header(HeaderName.CONTENT_TYPE, contentType, true); } } @@ -396,7 +398,8 @@ public class Request implements HeaderOperation { // endregion /** - * 获取最大重定向请求次数 + * 获取最大重定向请求次数
+ * 注意:当{@link ClientConfig#isFollowRedirects()}为{@code true}时,此参数无效 * * @return 最大重定向请求次数 */ @@ -406,7 +409,8 @@ public class Request implements HeaderOperation { /** * 设置最大重定向次数
- * 如果次数小于1则表示不重定向,大于等于1表示打开重定向 + * 如果次数小于1则表示不重定向,大于等于1表示打开重定向
+ * 注意:当{@link ClientConfig#isFollowRedirects()}为{@code true}时,此参数无效 * * @param maxRedirectCount 最大重定向次数 * @return this @@ -477,13 +481,14 @@ public class Request implements HeaderOperation { /** * 检查form表单中的对象是否为Multipart对象 + * * @param value 对象 * @return 是否为Multipart对象 */ - private static boolean hasMultipartValue(final Object value){ - if(value instanceof Iterable){ + private static boolean hasMultipartValue(final Object value) { + if (value instanceof Iterable) { for (final Object subValue : (Iterable) value) { - if(hasMultipartValue(subValue)){ + if (hasMultipartValue(subValue)) { return true; } } diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient4/HttpClient4Engine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient4/HttpClient4Engine.java index b17c2641b..5fbd7c047 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient4/HttpClient4Engine.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient4/HttpClient4Engine.java @@ -25,10 +25,7 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.BasicCredentialsProvider; -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.client.*; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicHeader; import org.dromara.hutool.core.io.IoUtil; @@ -118,7 +115,7 @@ public class HttpClient4Engine extends AbstractClientEngine { if (null != sslInfo) { clientBuilder.setSSLSocketFactory(buildSocketFactory(sslInfo)); } - if(config.isDisableCache()){ + if (config.isDisableCache()) { clientBuilder.disableAuthCaching(); } @@ -128,8 +125,12 @@ public class HttpClient4Engine extends AbstractClientEngine { // 设置默认头信息 clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers())); - // 默认关闭自动重定向 - clientBuilder.disableRedirectHandling(); + // 重定向 + if (config.isFollowRedirects()) { + clientBuilder.setRedirectStrategy(LaxRedirectStrategy.INSTANCE); + } else { + clientBuilder.disableRedirectHandling(); + } // 设置代理 setProxy(clientBuilder, config); @@ -156,7 +157,7 @@ public class HttpClient4Engine extends AbstractClientEngine { // 填充自定义消息体 final HttpBody body = message.handledBody(); - if(null != body){ + if (null != body) { requestBuilder.setEntity(new HttpClient4BodyEntity( // 用户自定义的内容类型 message.header(HeaderName.CONTENT_TYPE), @@ -194,6 +195,7 @@ public class HttpClient4Engine extends AbstractClientEngine { /** * 构建连接池管理器 + * * @param config 配置 * @return PoolingHttpClientConnectionManager */ @@ -201,7 +203,7 @@ public class HttpClient4Engine extends AbstractClientEngine { final PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(); // 连接池配置 - if(config instanceof HttpClientConfig){ + if (config instanceof HttpClientConfig) { final HttpClientConfig httpClientConfig = (HttpClientConfig) config; manager.setMaxTotal(httpClientConfig.getMaxTotal()); manager.setDefaultMaxPerRoute(httpClientConfig.getMaxPerRoute()); diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java index 62b0b62ba..da4540733 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java @@ -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.config.ConnectionConfig; 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.classic.CloseableHttpClient; 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); clientBuilder.setConnectionManager(buildConnectionManager(config)); clientBuilder.setDefaultRequestConfig(buildRequestConfig(config)); - if(config.isDisableCache()){ + if (config.isDisableCache()) { clientBuilder.disableAuthCaching(); } // 设置默认头信息 clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers())); - // 默认关闭自动重定向 - clientBuilder.disableRedirectHandling(); + // 重定向 + if (config.isFollowRedirects()) { + clientBuilder.setRedirectStrategy(DefaultRedirectStrategy.INSTANCE); + } else { + clientBuilder.disableRedirectHandling(); + } // 设置代理 setProxy(clientBuilder, config); @@ -153,7 +158,7 @@ public class HttpClient5Engine extends AbstractClientEngine { // 填充自定义消息体 final HttpBody body = message.handledBody(); - if(null != body){ + if (null != body) { request.setEntity(new HttpClient5BodyEntity( // 用户自定义的内容类型 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 int maxTotal = httpClientConfig.getMaxTotal(); final int maxPerRoute = httpClientConfig.getMaxPerRoute(); diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java index 3ce4d139a..435d517c6 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java @@ -129,8 +129,8 @@ public class JdkClientEngine extends AbstractClientEngine { .setReadTimeout(config.getReadTimeout()) .setMethod(message.method())// .setSSLInfo(config.getSslInfo()) - // 关闭JDK自动转发,采用手动转发方式 - .setInstanceFollowRedirects(false) + // 如果客户端设置自动重定向,则Request中maxRedirectCount无效 + .setInstanceFollowRedirects(config.isFollowRedirects()) .setDisableCache(config.isDisableCache()) // 覆盖默认Header .header(message.headers(), true); diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/okhttp/OkHttpEngine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/okhttp/OkHttpEngine.java index bb803fea0..1a330adb4 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/okhttp/OkHttpEngine.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/okhttp/OkHttpEngine.java @@ -129,8 +129,8 @@ public class OkHttpEngine extends AbstractClientEngine { // 设置代理 setProxy(builder, config); - // 默认关闭自动跳转 - builder.followRedirects(false); + // 重定向 + builder.followRedirects(config.isFollowRedirects()); this.client = builder.build(); }