add request config

This commit is contained in:
Looly 2024-09-05 21:17:10 +08:00
parent c314b4e183
commit c958553e76
11 changed files with 80 additions and 29 deletions

View File

@ -42,7 +42,7 @@ public class HttpGlobalConfig implements Serializable {
*/ */
private static int timeout = -1; private static int timeout = -1;
private static String boundary = "--------------------Hutool_" + RandomUtil.randomStringLower(16); private static String boundary = "--------------------Hutool_" + RandomUtil.randomStringLower(16);
private static int maxRedirectCount = 0; private static int maxRedirects = 0;
private static boolean ignoreEOFError = true; private static boolean ignoreEOFError = true;
/** /**
* 是否从响应正文中的meta标签获取编码信息 * 是否从响应正文中的meta标签获取编码信息
@ -99,10 +99,9 @@ public class HttpGlobalConfig implements Serializable {
* 如果设置为1表示重定向一次即请求两次 * 如果设置为1表示重定向一次即请求两次
* *
* @return 全局默认的最大重定向次数 * @return 全局默认的最大重定向次数
* @since 5.7.19
*/ */
public static int getMaxRedirectCount() { public static int getMaxRedirects() {
return maxRedirectCount; return maxRedirects;
} }
/** /**
@ -112,8 +111,8 @@ public class HttpGlobalConfig implements Serializable {
* @param customMaxRedirectCount 全局默认的最大重定向次数 * @param customMaxRedirectCount 全局默认的最大重定向次数
* @since 5.7.19 * @since 5.7.19
*/ */
synchronized public static void setMaxRedirectCount(final int customMaxRedirectCount) { synchronized public static void setMaxRedirects(final int customMaxRedirectCount) {
maxRedirectCount = customMaxRedirectCount; maxRedirects = customMaxRedirectCount;
} }
/** /**

View File

@ -211,7 +211,7 @@ public class ClientConfig {
/** /**
* 是否遇到响应状态码3xx时自动重定向请求<br> * 是否遇到响应状态码3xx时自动重定向请求<br>
* 注意当打开客户端级别的自动重定向{@link Request#maxRedirectCount()}无效 * 注意当打开客户端级别的自动重定向{@link Request#maxRedirects()}无效
* *
* @return 是否遇到响应状态码3xx时自动重定向请求 * @return 是否遇到响应状态码3xx时自动重定向请求
*/ */
@ -221,7 +221,7 @@ public class ClientConfig {
/** /**
* 设置是否遇到响应状态码3xx时自动重定向请求<br> * 设置是否遇到响应状态码3xx时自动重定向请求<br>
* 注意当打开客户端级别的自动重定向{@link Request#maxRedirectCount()}无效 * 注意当打开客户端级别的自动重定向{@link Request#maxRedirects()}无效
* *
* @param followRedirects 是否遇到响应状态码3xx时自动重定向请求 * @param followRedirects 是否遇到响应状态码3xx时自动重定向请求
* @return this * @return this

View File

@ -133,7 +133,7 @@ public class Request implements HeaderOperation<Request> {
/** /**
* 最大重定向次数 * 最大重定向次数
*/ */
private int maxRedirectCount; private int maxRedirects;
/** /**
* 是否是REST请求模式REST模式运行GET请求附带body * 是否是REST请求模式REST模式运行GET请求附带body
*/ */
@ -145,7 +145,7 @@ public class Request implements HeaderOperation<Request> {
public Request() { public Request() {
method = Method.GET; method = Method.GET;
headers = new ListValueMap<>(new LinkedHashMap<>()); headers = new ListValueMap<>(new LinkedHashMap<>());
maxRedirectCount = HttpGlobalConfig.getMaxRedirectCount(); maxRedirects = HttpGlobalConfig.getMaxRedirects();
// 全局默认请求头 // 全局默认请求头
header(GlobalHeaders.INSTANCE.headers(), false); header(GlobalHeaders.INSTANCE.headers(), false);
@ -403,8 +403,8 @@ public class Request implements HeaderOperation<Request> {
* *
* @return 最大重定向请求次数 * @return 最大重定向请求次数
*/ */
public int maxRedirectCount() { public int maxRedirects() {
return maxRedirectCount; return maxRedirects;
} }
/** /**
@ -412,11 +412,11 @@ public class Request implements HeaderOperation<Request> {
* 如果次数小于1则表示不重定向大于等于1表示打开重定向<br> * 如果次数小于1则表示不重定向大于等于1表示打开重定向<br>
* 注意{@link ClientConfig#isFollowRedirects()}{@code true}此参数无效 * 注意{@link ClientConfig#isFollowRedirects()}{@code true}此参数无效
* *
* @param maxRedirectCount 最大重定向次数 * @param maxRedirects 最大重定向次数
* @return this * @return this
*/ */
public Request setMaxRedirectCount(final int maxRedirectCount) { public Request setMaxRedirects(final int maxRedirects) {
this.maxRedirectCount = Math.max(maxRedirectCount, 0); this.maxRedirects = Math.max(maxRedirects, 0);
return this; return this;
} }

View File

@ -110,18 +110,24 @@ public class HttpClient4Engine extends AbstractClientEngine {
final HttpClientBuilder clientBuilder = HttpClients.custom(); final HttpClientBuilder clientBuilder = HttpClients.custom();
final ClientConfig config = ObjUtil.defaultIfNull(this.config, HttpClientConfig::of); final ClientConfig config = ObjUtil.defaultIfNull(this.config, HttpClientConfig::of);
// SSL配置 // SSL配置
final SSLInfo sslInfo = config.getSslInfo(); final SSLInfo sslInfo = config.getSslInfo();
if (null != sslInfo) { if (null != sslInfo) {
clientBuilder.setSSLSocketFactory(buildSocketFactory(sslInfo)); clientBuilder.setSSLSocketFactory(buildSocketFactory(sslInfo));
} }
// 连接配置
clientBuilder.setConnectionManager(buildConnectionManager(config));
// 实例级别默认请求配置
clientBuilder.setDefaultRequestConfig(buildRequestConfig(config));
// 缓存
if (config.isDisableCache()) { if (config.isDisableCache()) {
clientBuilder.disableAuthCaching(); clientBuilder.disableAuthCaching();
} }
clientBuilder.setConnectionManager(buildConnectionManager(config));
clientBuilder.setDefaultRequestConfig(buildRequestConfig(config));
// 设置默认头信息 // 设置默认头信息
clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers())); clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers()));
@ -152,6 +158,9 @@ public class HttpClient4Engine extends AbstractClientEngine {
.create(message.method().name()) .create(message.method().name())
.setUri(url.toURI()); .setUri(url.toURI());
// 自定义单次请求配置
requestBuilder.setConfig(buildRequestConfig(message));
// 填充自定义头 // 填充自定义头
message.headers().forEach((k, v1) -> v1.forEach((v2) -> requestBuilder.addHeader(k, v2))); message.headers().forEach((k, v1) -> v1.forEach((v2) -> requestBuilder.addHeader(k, v2)));
@ -212,6 +221,23 @@ public class HttpClient4Engine extends AbstractClientEngine {
return manager; return manager;
} }
/**
* 构建请求配置包括重定向
* @param request 请求
* @return {@link RequestConfig}
*/
private static RequestConfig buildRequestConfig(final Request request) {
final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
final int maxRedirects = request.maxRedirects();
if (maxRedirects > 0) {
requestConfigBuilder.setMaxRedirects(maxRedirects);
} else {
requestConfigBuilder.setRedirectsEnabled(false);
}
return requestConfigBuilder.build();
}
/** /**
* 构建请求配置包括连接请求超时和响应读取超时 * 构建请求配置包括连接请求超时和响应读取超时
* *

View File

@ -116,10 +116,15 @@ public class HttpClient5Engine extends AbstractClientEngine {
} }
final HttpClientBuilder clientBuilder = HttpClients.custom(); final HttpClientBuilder clientBuilder = HttpClients.custom();
final ClientConfig config = ObjUtil.defaultIfNull(this.config, HttpClientConfig::of); final ClientConfig config = ObjUtil.defaultIfNull(this.config, HttpClientConfig::of);
// 连接配置包括SSL配置等
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();
} }
@ -151,7 +156,10 @@ public class HttpClient5Engine extends AbstractClientEngine {
final UrlBuilder url = message.handledUrl(); final UrlBuilder url = message.handledUrl();
Assert.notNull(url, "Request URL must be not null!"); Assert.notNull(url, "Request URL must be not null!");
final ClassicHttpRequest request = new HttpUriRequestBase(message.method().name(), url.toURI()); final HttpUriRequestBase request = new HttpUriRequestBase(message.method().name(), url.toURI());
// 自定义单次请求配置
request.setConfig(buildRequestConfig(message));
// 填充自定义头 // 填充自定义头
request.setHeaders(toHeaderList(message.headers()).toArray(new Header[0])); request.setHeaders(toHeaderList(message.headers()).toArray(new Header[0]));
@ -222,6 +230,24 @@ public class HttpClient5Engine extends AbstractClientEngine {
return connectionManagerBuilder.build(); return connectionManagerBuilder.build();
} }
/**
* 构建请求配置包括重定向配置
*
* @param request 请求
* @return {@link RequestConfig}
*/
private static RequestConfig buildRequestConfig(final Request request) {
final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
final int maxRedirects = request.maxRedirects();
if (maxRedirects > 0) {
requestConfigBuilder.setMaxRedirects(maxRedirects);
} else {
requestConfigBuilder.setRedirectsEnabled(false);
}
return requestConfigBuilder.build();
}
/** /**
* 构建请求配置包括连接请求超时和响应读取超时 * 构建请求配置包括连接请求超时和响应读取超时
* *
@ -240,7 +266,7 @@ public class HttpClient5Engine extends AbstractClientEngine {
if (readTimeout > 0) { if (readTimeout > 0) {
requestConfigBuilder.setResponseTimeout(readTimeout, TimeUnit.MILLISECONDS); requestConfigBuilder.setResponseTimeout(readTimeout, TimeUnit.MILLISECONDS);
} }
if(config instanceof HttpClientConfig){ if (config instanceof HttpClientConfig) {
requestConfigBuilder.setMaxRedirects(((HttpClientConfig) config).getMaxRedirects()); requestConfigBuilder.setMaxRedirects(((HttpClientConfig) config).getMaxRedirects());
} }

View File

@ -163,7 +163,7 @@ public class JdkClientEngine extends AbstractClientEngine {
*/ */
private JdkHttpResponse sendRedirectIfPossible(final JdkHttpConnection conn, final Request message, final boolean isAsync) { private JdkHttpResponse sendRedirectIfPossible(final JdkHttpConnection conn, final Request message, final boolean isAsync) {
// 手动实现重定向 // 手动实现重定向
if (message.maxRedirectCount() > 0) { if (message.maxRedirects() > 0) {
final int code; final int code;
try { try {
code = conn.getCode(); code = conn.getCode();
@ -176,7 +176,7 @@ public class JdkClientEngine extends AbstractClientEngine {
if (code != HttpURLConnection.HTTP_OK) { if (code != HttpURLConnection.HTTP_OK) {
if (HttpStatus.isRedirected(code)) { if (HttpStatus.isRedirected(code)) {
message.url(getLocationUrl(message.handledUrl(), conn.header(HeaderName.LOCATION))); message.url(getLocationUrl(message.handledUrl(), conn.header(HeaderName.LOCATION)));
if (conn.redirectCount < message.maxRedirectCount()) { if (conn.redirectCount < message.maxRedirects()) {
conn.redirectCount++; conn.redirectCount++;
return send(message, isAsync); return send(message, isAsync);
} }

View File

@ -594,7 +594,7 @@ public class SoapClient implements HeaderOperation<SoapClient> {
public Response sendForResponse() { public Response sendForResponse() {
final Request request = Request.of(this.url) final Request request = Request.of(this.url)
.method(Method.POST) .method(Method.POST)
.setMaxRedirectCount(2) .setMaxRedirects(2)
.contentType(getXmlContentType()) .contentType(getXmlContentType())
.header(this.headers, false) .header(this.headers, false)
.body(getMsgStr(false)); .body(getMsgStr(false));

View File

@ -217,7 +217,7 @@ public class DownloadTest {
public void downloadTeamViewerTest() throws IOException { public void downloadTeamViewerTest() throws IOException {
// 此URL有3次重定向, 需要请求4次 // 此URL有3次重定向, 需要请求4次
final String url = "https://download.teamviewer.com/download/TeamViewer_Setup_x64.exe"; final String url = "https://download.teamviewer.com/download/TeamViewer_Setup_x64.exe";
HttpGlobalConfig.setMaxRedirectCount(20); HttpGlobalConfig.setMaxRedirects(20);
final Path temp = Files.createTempFile("tmp", ".exe"); final Path temp = Files.createTempFile("tmp", ".exe");
final File file = HttpDownloader.downloadFile(url, temp.toFile()); final File file = HttpDownloader.downloadFile(url, temp.toFile());
Console.log(file.length()); Console.log(file.length());

View File

@ -98,7 +98,7 @@ public class HttpUtilTest {
public void get12306Test() { public void get12306Test() {
// 某些网站需要打开信任全部域 // 某些网站需要打开信任全部域
// HttpGlobalConfig.setTrustAnyHost(true); // HttpGlobalConfig.setTrustAnyHost(true);
HttpUtil.send(Request.of("https://kyfw.12306.cn/otn/").setMaxRedirectCount(2)) HttpUtil.send(Request.of("https://kyfw.12306.cn/otn/").setMaxRedirects(2))
.then(response -> Console.log(response.bodyStr())); .then(response -> Console.log(response.bodyStr()));
} }

View File

@ -26,7 +26,7 @@ public class IssueI5TPSYTest {
public void redirectTest() { public void redirectTest() {
final String url = "https://bsxt.gdzwfw.gov.cn/UnifiedReporting/auth/newIndex"; final String url = "https://bsxt.gdzwfw.gov.cn/UnifiedReporting/auth/newIndex";
final Response res = HttpUtil.send(Request.of(url) final Response res = HttpUtil.send(Request.of(url)
.setMaxRedirectCount(2) .setMaxRedirects(2)
.header(HeaderName.USER_AGENT, "PostmanRuntime/7.29.2") .header(HeaderName.USER_AGENT, "PostmanRuntime/7.29.2")
.cookie("jsessionid=s%3ANq6YTcIHQWrHkEqOSxiQNijDMhoFNV4_.h2MVD1CkW7sOZ60OSnPs7m4K%2FhENfYy%2FdzjKvSiZF4E")); .cookie("jsessionid=s%3ANq6YTcIHQWrHkEqOSxiQNijDMhoFNV4_.h2MVD1CkW7sOZ60OSnPs7m4K%2FhENfYy%2FdzjKvSiZF4E"));
Console.log(res.body()); Console.log(res.body());

View File

@ -168,12 +168,12 @@ public class RequestTest {
// String url = "https://api.btstu.cn/sjtx/api.php?lx=b1"; // String url = "https://api.btstu.cn/sjtx/api.php?lx=b1";
// 方式1全局设置 // 方式1全局设置
HttpGlobalConfig.setMaxRedirectCount(1); HttpGlobalConfig.setMaxRedirects(1);
Response execute = Request.of(url).send(); Response execute = Request.of(url).send();
Console.log(execute.getStatus(), execute.header(HeaderName.LOCATION)); Console.log(execute.getStatus(), execute.header(HeaderName.LOCATION));
// 方式2单独设置 // 方式2单独设置
execute = Request.of(url).setMaxRedirectCount(1).send(); execute = Request.of(url).setMaxRedirects(1).send();
Console.log(execute.getStatus(), execute.header(HeaderName.LOCATION)); Console.log(execute.getStatus(), execute.header(HeaderName.LOCATION));
} }