mirror of
https://gitee.com/dromara/hutool.git
synced 2025-08-20 00:44:27 +08:00
add jdk11+ HttpClient support
This commit is contained in:
parent
10d660fb06
commit
ef6fc50fbb
@ -29,7 +29,7 @@ public class SimpleWrapper<T> implements Wrapper<T> {
|
||||
/**
|
||||
* 原始对象
|
||||
*/
|
||||
protected final T raw;
|
||||
protected T raw;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -66,7 +66,7 @@ public class ClientEngineFactory {
|
||||
/**
|
||||
* 创建自定义引擎
|
||||
*
|
||||
* @param engineName 引擎名称,忽略大小写,如`HttpClient4`、`HttpClient5`、`OkHttp`、`JdkClient`
|
||||
* @param engineName 引擎名称,忽略大小写,如`HttpClient4`、`HttpClient5`、`OkHttp`、`JdkClient`、`Jdk11Client`
|
||||
* @return 引擎
|
||||
* @throws HttpException 无对应名称的引擎
|
||||
*/
|
||||
|
@ -24,6 +24,8 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import cn.hutool.v7.core.lang.builder.Builder;
|
||||
import cn.hutool.v7.http.ssl.SSLInfo;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* HttpClient4连接工厂注册器构建器
|
||||
*
|
||||
@ -31,6 +33,7 @@ import cn.hutool.v7.http.ssl.SSLInfo;
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class ConnectionSocketFactoryRegistryBuilder implements Builder<Registry<ConnectionSocketFactory>> {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,126 @@
|
||||
package cn.hutool.v7.http.client.engine.jdk11;
|
||||
|
||||
import cn.hutool.v7.http.HttpException;
|
||||
import cn.hutool.v7.http.client.ClientConfig;
|
||||
import cn.hutool.v7.http.client.Request;
|
||||
import cn.hutool.v7.http.client.Response;
|
||||
import cn.hutool.v7.http.client.cookie.InMemoryCookieStore;
|
||||
import cn.hutool.v7.http.client.engine.AbstractClientEngine;
|
||||
import cn.hutool.v7.http.client.engine.jdk.JdkCookieManager;
|
||||
import cn.hutool.v7.http.proxy.ProxyInfo;
|
||||
import cn.hutool.v7.http.ssl.SSLInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* JDK11 HttpClient引擎实现
|
||||
*
|
||||
* @author looly
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public class Jdk11ClientEngine extends AbstractClientEngine {
|
||||
|
||||
/**
|
||||
* HttpClient
|
||||
*/
|
||||
private HttpClient client;
|
||||
/**
|
||||
* Cookie管理
|
||||
*/
|
||||
private JdkCookieManager cookieManager;
|
||||
|
||||
/**
|
||||
* 获取Cookie管理器
|
||||
*
|
||||
* @return Cookie管理器
|
||||
*/
|
||||
public JdkCookieManager getCookieManager() {
|
||||
return this.cookieManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response send(final Request message) {
|
||||
initEngine();
|
||||
|
||||
final HttpRequest.Builder builder = HttpRequest.newBuilder()
|
||||
.uri(message.url().toURI())
|
||||
.method(message.method().name(), null == message.body() ?
|
||||
HttpRequest.BodyPublishers.noBody() :
|
||||
HttpRequest.BodyPublishers.ofInputStream(message::bodyStream));
|
||||
|
||||
// Read超时
|
||||
if(null != this.config){
|
||||
builder.timeout(Duration.ofMillis(this.config.getReadTimeout()));
|
||||
}
|
||||
|
||||
// 自定义Headers
|
||||
message.headers().forEach((k, v1) -> v1.forEach(v2 -> builder.header(k, v2)));
|
||||
|
||||
final HttpResponse<InputStream> response;
|
||||
try {
|
||||
response = this.client.send(builder.build(), HttpResponse.BodyHandlers.ofInputStream());
|
||||
} catch (final Exception e) {
|
||||
throw new HttpException(e);
|
||||
}
|
||||
|
||||
return new Jdk11HttpResponse(response, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRawEngine() {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// 关闭Cookie管理器
|
||||
this.cookieManager = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reset() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initEngine() {
|
||||
if (null != this.client) {
|
||||
return;
|
||||
}
|
||||
|
||||
final HttpClient.Builder builder = HttpClient.newBuilder()
|
||||
.version(HttpClient.Version.HTTP_1_1);
|
||||
|
||||
final ClientConfig config = this.config;
|
||||
if(null != config){
|
||||
builder.connectTimeout(Duration.ofMillis(config.getConnectionTimeout()));
|
||||
|
||||
// SSL
|
||||
final SSLInfo sslInfo = config.getSslInfo();
|
||||
if(null != sslInfo){
|
||||
builder.sslContext(sslInfo.getSslContext());
|
||||
}
|
||||
|
||||
// Cookie
|
||||
if (config.isUseCookieManager()) {
|
||||
this.cookieStore = new InMemoryCookieStore();
|
||||
this.cookieManager = new JdkCookieManager(this.cookieStore);
|
||||
builder.cookieHandler(this.cookieManager.getCookieManager());
|
||||
}
|
||||
|
||||
// Proxy
|
||||
final ProxyInfo proxy = config.getProxy();
|
||||
if (null != proxy) {
|
||||
builder.proxy(proxy.getProxySelector());
|
||||
}
|
||||
}
|
||||
|
||||
this.client = builder.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package cn.hutool.v7.http.client.engine.jdk11;
|
||||
|
||||
import cn.hutool.v7.core.lang.wrapper.SimpleWrapper;
|
||||
import cn.hutool.v7.http.GlobalCompressStreamRegister;
|
||||
import cn.hutool.v7.http.HttpUtil;
|
||||
import cn.hutool.v7.http.client.Request;
|
||||
import cn.hutool.v7.http.client.Response;
|
||||
import cn.hutool.v7.http.client.body.ResponseBody;
|
||||
import cn.hutool.v7.http.meta.HeaderName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* JDK11 Http响应包装类
|
||||
*
|
||||
* @author looly
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public class Jdk11HttpResponse extends SimpleWrapper<HttpResponse<InputStream>> implements Response {
|
||||
|
||||
/**
|
||||
* 响应头
|
||||
*/
|
||||
private final Map<String, List<String>> headers;
|
||||
/**
|
||||
* 响应内容体,{@code null} 表示无内容
|
||||
*/
|
||||
private final ResponseBody body;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param rawRes 原始响应
|
||||
* @param message 请求信息
|
||||
*/
|
||||
public Jdk11HttpResponse(final HttpResponse<InputStream> rawRes, final Request message) {
|
||||
super(rawRes);
|
||||
this.headers = this.raw.headers().map();
|
||||
this.body = message.method().isIgnoreBody() ? null : new ResponseBody(this, bodyStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus() {
|
||||
return this.raw.statusCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String header(final String name) {
|
||||
return HttpUtil.header(this.headers, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> headers() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream bodyStream() {
|
||||
// 直接取得解压后的原始流
|
||||
return GlobalCompressStreamRegister.INSTANCE.wrapStream(this.raw.body(),
|
||||
header(HeaderName.CONTENT_ENCODING.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response sync() {
|
||||
final ResponseBody body = this.body;
|
||||
if(null != body){
|
||||
body.sync();
|
||||
}
|
||||
this.raw = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseBody body() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// ignore
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 基于JDK17+的HttpClient 封装的HTTP客户端
|
||||
*
|
||||
* @author Looly
|
||||
* @since 7.0.0
|
||||
*/
|
||||
package cn.hutool.v7.http.client.engine.jdk11;
|
@ -78,10 +78,6 @@ public class OkHttpResponse implements Response {
|
||||
@Override
|
||||
public InputStream bodyStream() {
|
||||
final okhttp3.ResponseBody body = rawRes.body();
|
||||
if(null == body){
|
||||
return EmptyInputStream.INSTANCE;
|
||||
}
|
||||
|
||||
return GlobalCompressStreamRegister.INSTANCE.wrapStream(body.byteStream(),
|
||||
this.rawRes.header(HeaderName.CONTENT_ENCODING.getValue()));
|
||||
}
|
||||
|
@ -18,3 +18,4 @@ cn.hutool.v7.http.client.engine.httpclient5.HttpClient5Engine
|
||||
cn.hutool.v7.http.client.engine.httpclient4.HttpClient4Engine
|
||||
cn.hutool.v7.http.client.engine.okhttp.OkHttpEngine
|
||||
cn.hutool.v7.http.client.engine.jdk.JdkClientEngine
|
||||
cn.hutool.v7.http.client.engine.jdk11.Jdk11ClientEngine
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2025 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 cn.hutool.v7.http.client;
|
||||
|
||||
import cn.hutool.v7.core.lang.Console;
|
||||
import cn.hutool.v7.http.HttpUtil;
|
||||
import cn.hutool.v7.http.client.engine.ClientEngine;
|
||||
import cn.hutool.v7.http.meta.Method;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class Jdk11HttpClientEngineTest {
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
@Disabled
|
||||
public void getTest() {
|
||||
final ClientEngine engine = HttpUtil.createClient("jdk11Client");
|
||||
|
||||
final Request req = Request.of("https://www.hutool.cn/").method(Method.GET);
|
||||
final Response res = engine.send(req);
|
||||
|
||||
Console.log(res.getStatus());
|
||||
Console.log(res.bodyStr());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user