mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-24 18:04:54 +08:00
add EngineRequestBuilder
This commit is contained in:
parent
b15d6458f3
commit
fb6302f1a2
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine;
|
||||
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
|
||||
/**
|
||||
* 引擎的请求对象构建器<br》
|
||||
* 用于将{@link Request}转换为引擎对应的请求对象
|
||||
*
|
||||
* @param <T> 引擎请求对象类型
|
||||
*/
|
||||
public interface EngineRequestBuilder<T> {
|
||||
|
||||
/**
|
||||
* 构建引擎请求对象
|
||||
*
|
||||
* @param message 请求对象
|
||||
* @return 引擎请求对象
|
||||
*/
|
||||
T build(Request message);
|
||||
}
|
@ -23,15 +23,16 @@ import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
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.*;
|
||||
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.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.impl.conn.SystemDefaultRoutePlanner;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.net.url.UrlBuilder;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.http.GlobalHeaders;
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
@ -39,10 +40,8 @@ import org.dromara.hutool.http.client.ApacheHttpClientConfig;
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.Response;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
import org.dromara.hutool.http.proxy.ProxyInfo;
|
||||
import org.dromara.hutool.http.ssl.SSLInfo;
|
||||
|
||||
@ -77,10 +76,9 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
public Response send(final Request message) {
|
||||
initEngine();
|
||||
|
||||
final HttpUriRequest request = buildRequest(message);
|
||||
final HttpUriRequest request = HttpUriRequestBuilder.INSTANCE.build(message);
|
||||
final CloseableHttpResponse response;
|
||||
try {
|
||||
//return this.engine.execute(request, response -> new HttpClient4Response(response, message));
|
||||
response = this.engine.execute(request);
|
||||
} catch (final IOException e) {
|
||||
throw new HttpException(e);
|
||||
@ -124,7 +122,7 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
clientBuilder.setConnectionManager(buildConnectionManager(config));
|
||||
|
||||
// 实例级别默认请求配置
|
||||
clientBuilder.setDefaultRequestConfig(buildRequestConfig(config));
|
||||
clientBuilder.setDefaultRequestConfig(buildDefaultRequestConfig(config));
|
||||
|
||||
// 缓存
|
||||
if (config.isDisableCache()) {
|
||||
@ -146,40 +144,6 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
this.engine = clientBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求体
|
||||
*
|
||||
* @param message {@link Request}
|
||||
* @return {@link HttpUriRequest}
|
||||
*/
|
||||
private static HttpUriRequest buildRequest(final Request message) {
|
||||
final UrlBuilder url = message.handledUrl();
|
||||
Assert.notNull(url, "Request URL must be not null!");
|
||||
|
||||
final RequestBuilder requestBuilder = RequestBuilder
|
||||
.create(message.method().name())
|
||||
.setUri(url.toURI());
|
||||
|
||||
// 自定义单次请求配置
|
||||
requestBuilder.setConfig(buildRequestConfig(message));
|
||||
|
||||
// 填充自定义头
|
||||
message.headers().forEach((k, v1) -> v1.forEach((v2) -> requestBuilder.addHeader(k, v2)));
|
||||
|
||||
// 填充自定义消息体
|
||||
final HttpBody body = message.handledBody();
|
||||
if (null != body) {
|
||||
requestBuilder.setEntity(new HttpClient4BodyEntity(
|
||||
// 用户自定义的内容类型
|
||||
message.header(HeaderName.CONTENT_TYPE),
|
||||
message.contentEncoding(),
|
||||
message.isChunked(),
|
||||
body));
|
||||
}
|
||||
|
||||
return requestBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认头列表
|
||||
*
|
||||
@ -229,31 +193,13 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求配置,包括连接请求超时和响应(读取)超时
|
||||
*
|
||||
* @param config {@link ClientConfig}
|
||||
* @return {@link RequestConfig}
|
||||
*/
|
||||
private static RequestConfig buildRequestConfig(final ClientConfig config) {
|
||||
private static RequestConfig buildDefaultRequestConfig(final ClientConfig config) {
|
||||
// 请求配置
|
||||
final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
|
||||
|
||||
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.httpclient4;
|
||||
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.methods.RequestBuilder;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.net.url.UrlBuilder;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.engine.EngineRequestBuilder;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
|
||||
/**
|
||||
* HttpClient4请求构建器
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class HttpUriRequestBuilder implements EngineRequestBuilder<HttpUriRequest> {
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*/
|
||||
public static final HttpUriRequestBuilder INSTANCE = new HttpUriRequestBuilder();
|
||||
|
||||
@Override
|
||||
public HttpUriRequest build(final Request message) {
|
||||
final UrlBuilder url = message.handledUrl();
|
||||
Assert.notNull(url, "Request URL must be not null!");
|
||||
|
||||
final RequestBuilder requestBuilder = RequestBuilder
|
||||
.create(message.method().name())
|
||||
.setUri(url.toURI());
|
||||
|
||||
// 自定义单次请求配置
|
||||
requestBuilder.setConfig(buildRequestConfig(message));
|
||||
|
||||
// 填充自定义头
|
||||
message.headers().forEach((k, v1) -> v1.forEach((v2) -> requestBuilder.addHeader(k, v2)));
|
||||
|
||||
// 填充自定义消息体
|
||||
final HttpBody body = message.handledBody();
|
||||
if (null != body) {
|
||||
requestBuilder.setEntity(new HttpClient4BodyEntity(
|
||||
// 用户自定义的内容类型
|
||||
message.header(HeaderName.CONTENT_TYPE),
|
||||
message.contentEncoding(),
|
||||
message.isChunked(),
|
||||
body));
|
||||
}
|
||||
|
||||
return requestBuilder.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();
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.httpclient5;
|
||||
|
||||
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.net.url.UrlBuilder;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.engine.EngineRequestBuilder;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* HttpClient5请求构建器
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class ClassicHttpRequestBuilder implements EngineRequestBuilder<ClassicHttpRequest> {
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*/
|
||||
public static ClassicHttpRequestBuilder INSTANCE = new ClassicHttpRequestBuilder();
|
||||
|
||||
@Override
|
||||
public ClassicHttpRequest build(final Request message) {
|
||||
final UrlBuilder url = message.handledUrl();
|
||||
Assert.notNull(url, "Request URL must be not null!");
|
||||
|
||||
final HttpUriRequestBase request = new HttpUriRequestBase(message.method().name(), url.toURI());
|
||||
|
||||
// 自定义单次请求配置
|
||||
request.setConfig(buildRequestConfig(message));
|
||||
|
||||
// 填充自定义头
|
||||
request.setHeaders(toHeaderList(message.headers()).toArray(new Header[0]));
|
||||
|
||||
// 填充自定义消息体
|
||||
final HttpBody body = message.handledBody();
|
||||
if (null != body) {
|
||||
request.setEntity(new HttpClient5BodyEntity(
|
||||
// 用户自定义的内容类型
|
||||
message.header(HeaderName.CONTENT_TYPE),
|
||||
message.contentEncoding(),
|
||||
message.isChunked(),
|
||||
body));
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认头列表
|
||||
*
|
||||
* @return 默认头列表
|
||||
*/
|
||||
private static List<Header> toHeaderList(final Map<String, ? extends Collection<String>> headersMap) {
|
||||
final List<Header> result = new ArrayList<>();
|
||||
headersMap.forEach((k, v1) -> v1.forEach((v2) -> result.add(new BasicHeader(k, v2))));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求配置,包括重定向配置
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@ package org.dromara.hutool.http.client.engine.httpclient5;
|
||||
|
||||
import org.apache.hc.client5.http.auth.AuthScope;
|
||||
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.auth.BasicCredentialsProvider;
|
||||
@ -34,7 +33,6 @@ import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.net.url.UrlBuilder;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.http.GlobalHeaders;
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
@ -42,10 +40,8 @@ import org.dromara.hutool.http.client.ApacheHttpClientConfig;
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.Response;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
import org.dromara.hutool.http.proxy.ProxyInfo;
|
||||
import org.dromara.hutool.http.ssl.SSLInfo;
|
||||
|
||||
@ -80,7 +76,7 @@ public class HttpClient5Engine extends AbstractClientEngine {
|
||||
public Response send(final Request message) {
|
||||
initEngine();
|
||||
|
||||
final ClassicHttpRequest request = buildRequest(message);
|
||||
final ClassicHttpRequest request = ClassicHttpRequestBuilder.INSTANCE.build(message);
|
||||
final ClassicHttpResponse response;
|
||||
try {
|
||||
//return this.engine.execute(request, (response -> new HttpClient5Response(response, message)));
|
||||
@ -143,39 +139,6 @@ public class HttpClient5Engine extends AbstractClientEngine {
|
||||
this.engine = clientBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求体
|
||||
*
|
||||
* @param message {@link Request}
|
||||
* @return {@link ClassicHttpRequest}
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private static ClassicHttpRequest buildRequest(final Request message) {
|
||||
final UrlBuilder url = message.handledUrl();
|
||||
Assert.notNull(url, "Request URL must be not null!");
|
||||
|
||||
final HttpUriRequestBase request = new HttpUriRequestBase(message.method().name(), url.toURI());
|
||||
|
||||
// 自定义单次请求配置
|
||||
request.setConfig(buildRequestConfig(message));
|
||||
|
||||
// 填充自定义头
|
||||
request.setHeaders(toHeaderList(message.headers()).toArray(new Header[0]));
|
||||
|
||||
// 填充自定义消息体
|
||||
final HttpBody body = message.handledBody();
|
||||
if (null != body) {
|
||||
request.setEntity(new HttpClient5BodyEntity(
|
||||
// 用户自定义的内容类型
|
||||
message.header(HeaderName.CONTENT_TYPE),
|
||||
message.contentEncoding(),
|
||||
message.isChunked(),
|
||||
body));
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认头列表
|
||||
*
|
||||
@ -234,24 +197,6 @@ public class HttpClient5Engine extends AbstractClientEngine {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建默认请求配置,包括连接请求超时和响应(读取)超时
|
||||
*
|
||||
|
@ -17,22 +17,17 @@
|
||||
package org.dromara.hutool.http.client.engine.jdk;
|
||||
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.net.url.UrlUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.RequestContext;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
import org.dromara.hutool.http.meta.HttpStatus;
|
||||
import org.dromara.hutool.http.meta.Method;
|
||||
import org.dromara.hutool.http.proxy.ProxyInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* 基于JDK的UrlConnection的Http客户端引擎实现
|
||||
@ -63,6 +58,7 @@ public class JdkClientEngine extends AbstractClientEngine {
|
||||
|
||||
@Override
|
||||
public JdkHttpResponse send(final Request message) {
|
||||
initEngine();
|
||||
return doSend(new RequestContext(message));
|
||||
}
|
||||
|
||||
@ -84,12 +80,24 @@ public class JdkClientEngine extends AbstractClientEngine {
|
||||
|
||||
@Override
|
||||
protected void initEngine() {
|
||||
this.cookieManager = (null != this.config && this.config.isUseCookieManager()) ? new JdkCookieManager() : new JdkCookieManager(null);
|
||||
if(null != this.cookieManager){
|
||||
return;
|
||||
}
|
||||
if(null != this.config && this.config.isUseCookieManager()){
|
||||
this.cookieStore = new InMemoryCookieStore();
|
||||
this.cookieManager = new JdkCookieManager(this.cookieStore);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求
|
||||
*
|
||||
* @param context 请求上下文
|
||||
* @return 响应对象
|
||||
*/
|
||||
private JdkHttpResponse doSend(final RequestContext context) {
|
||||
final Request message = context.getRequest();
|
||||
final JdkHttpConnection conn = buildConn(message);
|
||||
final JdkHttpConnection conn = new JdkRequestBuilder(this.config, this.cookieManager).build(message);
|
||||
try {
|
||||
doSend(conn, message);
|
||||
} catch (final IOException e) {
|
||||
@ -146,52 +154,4 @@ public class JdkClientEngine extends AbstractClientEngine {
|
||||
// 非Rest简单GET请求
|
||||
conn.connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建{@link JdkHttpConnection}
|
||||
*
|
||||
* @param message {@link Request}消息
|
||||
* @return {@link JdkHttpConnection}
|
||||
*/
|
||||
private JdkHttpConnection buildConn(final Request message) {
|
||||
final ClientConfig config = ObjUtil.defaultIfNull(this.config, ClientConfig::of);
|
||||
|
||||
final URL url = message.handledUrl().toURL();
|
||||
Proxy proxy = null;
|
||||
final ProxyInfo proxyInfo = config.getProxy();
|
||||
if (null != proxyInfo) {
|
||||
proxy = proxyInfo.selectFirst(UrlUtil.toURI(url));
|
||||
}
|
||||
final JdkHttpConnection conn = JdkHttpConnection
|
||||
.of(url, proxy)
|
||||
.setConnectTimeout(config.getConnectionTimeout())
|
||||
.setReadTimeout(config.getReadTimeout())
|
||||
.setMethod(message.method())//
|
||||
.setSSLInfo(config.getSslInfo())
|
||||
// 关闭自动重定向,手动处理重定向
|
||||
.setInstanceFollowRedirects(false)
|
||||
.setDisableCache(config.isDisableCache())
|
||||
// 覆盖默认Header
|
||||
.header(message.headers(), true);
|
||||
|
||||
if (!message.method().isIgnoreBody()) {
|
||||
// 在允许发送body的情况下,如果用户自定义了Content-Length,则使用用户定义的值
|
||||
final long contentLength = message.contentLength();
|
||||
if (contentLength > 0) {
|
||||
// 固定请求长度
|
||||
conn.setFixedLengthStreamingMode(contentLength);
|
||||
} else if (message.isChunked()) {
|
||||
conn.setChunkedStreamingMode(4096);
|
||||
}
|
||||
}
|
||||
|
||||
// Cookie管理
|
||||
if (null == message.header(HeaderName.COOKIE) && null != this.cookieManager) {
|
||||
// 用户没有自定义Cookie,则读取Cookie管理器中的信息并附带到请求中
|
||||
// 不覆盖模式回填Cookie头,这样用户定义的Cookie将优先
|
||||
conn.header(this.cookieManager.loadForRequest(conn), false);
|
||||
}
|
||||
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,8 @@ package org.dromara.hutool.http.client.engine.jdk;
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.net.url.UrlUtil;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.cookie.CookieStoreSpi;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.CookieManager;
|
||||
import java.net.CookiePolicy;
|
||||
@ -42,15 +41,17 @@ import java.util.Map;
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class JdkCookieManager implements Closeable {
|
||||
public class JdkCookieManager {
|
||||
|
||||
private CookieManager cookieManager;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param cookieStore {@link CookieStoreSpi}
|
||||
*/
|
||||
public JdkCookieManager() {
|
||||
this(new CookieManager(new JdkCookieStore(new InMemoryCookieStore()), CookiePolicy.ACCEPT_ALL));
|
||||
public JdkCookieManager(final CookieStoreSpi cookieStore) {
|
||||
this(new CookieManager(new JdkCookieStore(cookieStore), CookiePolicy.ACCEPT_ALL));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,20 +63,6 @@ public class JdkCookieManager implements Closeable {
|
||||
this.cookieManager = raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否启用Cookie管理
|
||||
*
|
||||
* @return 是否启用Cookie管理
|
||||
*/
|
||||
public boolean isEnable() {
|
||||
return null != this.cookieManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.cookieManager = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取{@link CookieManager}
|
||||
*
|
||||
|
@ -133,7 +133,7 @@ public class JdkHttpResponse implements Response, Closeable {
|
||||
* @return Cookie列表
|
||||
*/
|
||||
public List<HttpCookie> getCookies() {
|
||||
if (this.cookieManager.isEnable()) {
|
||||
if (null != this.cookieManager) {
|
||||
return this.cookieManager.getCookies(this.httpConnection);
|
||||
}
|
||||
return HttpCookie.parse(this.header(HeaderName.SET_COOKIE));
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.jdk;
|
||||
|
||||
import org.dromara.hutool.core.net.url.UrlUtil;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.engine.EngineRequestBuilder;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
import org.dromara.hutool.http.proxy.ProxyInfo;
|
||||
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* JDK Http请求构建器
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class JdkRequestBuilder implements EngineRequestBuilder<JdkHttpConnection> {
|
||||
|
||||
private final ClientConfig config;
|
||||
private final JdkCookieManager cookieManager;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param config 客户端配置,为null则使用默认配置
|
||||
* @param cookieManager Cookie管理器
|
||||
*/
|
||||
public JdkRequestBuilder(final ClientConfig config, final JdkCookieManager cookieManager) {
|
||||
this.config = ObjUtil.defaultIfNull(config, ClientConfig::of);
|
||||
this.cookieManager = cookieManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdkHttpConnection build(final Request message) {
|
||||
final ClientConfig config = this.config;
|
||||
|
||||
final URL url = message.handledUrl().toURL();
|
||||
Proxy proxy = null;
|
||||
final ProxyInfo proxyInfo = config.getProxy();
|
||||
if (null != proxyInfo) {
|
||||
proxy = proxyInfo.selectFirst(UrlUtil.toURI(url));
|
||||
}
|
||||
final JdkHttpConnection conn = JdkHttpConnection
|
||||
.of(url, proxy)
|
||||
.setConnectTimeout(config.getConnectionTimeout())
|
||||
.setReadTimeout(config.getReadTimeout())
|
||||
.setMethod(message.method())//
|
||||
.setSSLInfo(config.getSslInfo())
|
||||
// 关闭自动重定向,手动处理重定向
|
||||
.setInstanceFollowRedirects(false)
|
||||
.setDisableCache(config.isDisableCache())
|
||||
// 覆盖默认Header
|
||||
.header(message.headers(), true);
|
||||
|
||||
if (!message.method().isIgnoreBody()) {
|
||||
// 在允许发送body的情况下,如果用户自定义了Content-Length,则使用用户定义的值
|
||||
final long contentLength = message.contentLength();
|
||||
if (contentLength > 0) {
|
||||
// 固定请求长度
|
||||
conn.setFixedLengthStreamingMode(contentLength);
|
||||
} else if (message.isChunked()) {
|
||||
conn.setChunkedStreamingMode(4096);
|
||||
}
|
||||
}
|
||||
|
||||
// Cookie管理
|
||||
if (null == message.header(HeaderName.COOKIE) && null != this.cookieManager) {
|
||||
// 用户没有自定义Cookie,则读取Cookie管理器中的信息并附带到请求中
|
||||
// 不覆盖模式回填Cookie头,这样用户定义的Cookie将优先
|
||||
conn.header(this.cookieManager.loadForRequest(conn), false);
|
||||
}
|
||||
|
||||
return conn;
|
||||
}
|
||||
}
|
@ -17,7 +17,6 @@
|
||||
package org.dromara.hutool.http.client.engine.okhttp;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.internal.http.HttpMethod;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.util.ObjUtil;
|
||||
import org.dromara.hutool.http.HttpException;
|
||||
@ -25,7 +24,6 @@ import org.dromara.hutool.http.client.ClientConfig;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.RequestContext;
|
||||
import org.dromara.hutool.http.client.Response;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
|
||||
import org.dromara.hutool.http.meta.HeaderName;
|
||||
@ -149,9 +147,11 @@ public class OkHttpEngine extends AbstractClientEngine {
|
||||
*/
|
||||
private Response doSend(final RequestContext context) {
|
||||
final Request message = context.getRequest();
|
||||
|
||||
final okhttp3.Request request = OkHttpRequestBuilder.INSTANCE.build(message);
|
||||
final okhttp3.Response response;
|
||||
try {
|
||||
response = client.newCall(buildRequest(message)).execute();
|
||||
response = client.newCall(request).execute();
|
||||
} catch (final IOException e) {
|
||||
throw new HttpException(e);
|
||||
}
|
||||
@ -178,32 +178,6 @@ public class OkHttpEngine extends AbstractClientEngine {
|
||||
return new OkHttpResponse(response, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求体
|
||||
*
|
||||
* @param message {@link Request}
|
||||
* @return {@link okhttp3.Request}
|
||||
*/
|
||||
private static okhttp3.Request buildRequest(final Request message) {
|
||||
final okhttp3.Request.Builder builder = new okhttp3.Request.Builder()
|
||||
.url(message.handledUrl().toURL());
|
||||
|
||||
// 填充方法
|
||||
final String method = message.method().name();
|
||||
final HttpBody body = message.handledBody();
|
||||
if (null != body || HttpMethod.requiresRequestBody(method)) {
|
||||
// okhttp中,POST等请求必须提供body,否则会抛异常,此处传空的OkHttpRequestBody
|
||||
// 为了兼容支持rest请求,在此不区分是否为GET等方法,一律按照body是否有值填充,兼容
|
||||
builder.method(method, new OkHttpRequestBody(body));
|
||||
} else {
|
||||
builder.method(method, null);
|
||||
}
|
||||
|
||||
// 填充头信息
|
||||
message.headers().forEach((key, values) -> values.forEach(value -> builder.addHeader(key, value)));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置代理信息
|
||||
*
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.okhttp;
|
||||
|
||||
import okhttp3.internal.http.HttpMethod;
|
||||
import org.dromara.hutool.http.client.Request;
|
||||
import org.dromara.hutool.http.client.body.HttpBody;
|
||||
import org.dromara.hutool.http.client.engine.EngineRequestBuilder;
|
||||
|
||||
/**
|
||||
* OkHttp请求构建器
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class OkHttpRequestBuilder implements EngineRequestBuilder<okhttp3.Request> {
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*/
|
||||
public static final OkHttpRequestBuilder INSTANCE = new OkHttpRequestBuilder();
|
||||
|
||||
@Override
|
||||
public okhttp3.Request build(final Request message) {
|
||||
final okhttp3.Request.Builder builder = new okhttp3.Request.Builder()
|
||||
.url(message.handledUrl().toURL());
|
||||
|
||||
// 填充方法
|
||||
final String method = message.method().name();
|
||||
final HttpBody body = message.handledBody();
|
||||
if (null != body || HttpMethod.requiresRequestBody(method)) {
|
||||
// okhttp中,POST等请求必须提供body,否则会抛异常,此处传空的OkHttpRequestBody
|
||||
// 为了兼容支持rest请求,在此不区分是否为GET等方法,一律按照body是否有值填充,兼容
|
||||
builder.method(method, new OkHttpRequestBody(body));
|
||||
} else {
|
||||
builder.method(method, null);
|
||||
}
|
||||
|
||||
// 填充头信息
|
||||
message.headers().forEach((key, values) -> values.forEach(value -> builder.addHeader(key, value)));
|
||||
return builder.build();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user