diff --git a/CHANGELOG.md b/CHANGELOG.md
index 104033182..917764096 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@
* 【socket 】 SocketUtil增加connection方法
* 【extra 】 JschUtil增加bindPort重载方法(issue#I44UTH@Github)
* 【core 】 DefaultTrustManager改为继承X509ExtendedTrustManager
+* 【core 】 增加IoCopier
### 🐞Bug修复
* 【core 】 改进NumberChineseFormatter算法,补充完整单元测试,解决零问题
diff --git a/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java
index e78861af0..5a6a9fad3 100644
--- a/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/io/IoUtil.java
@@ -3,6 +3,8 @@ package cn.hutool.core.io;
import cn.hutool.core.collection.LineIter;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.exceptions.UtilException;
+import cn.hutool.core.io.copy.ReaderWriterCopier;
+import cn.hutool.core.io.copy.StreamCopier;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
@@ -86,28 +88,21 @@ public class IoUtil extends NioUtil {
* @throws IORuntimeException IO异常
*/
public static long copy(Reader reader, Writer writer, int bufferSize, StreamProgress streamProgress) throws IORuntimeException {
- char[] buffer = new char[bufferSize];
- long size = 0;
- int readSize;
- if (null != streamProgress) {
- streamProgress.start();
- }
- try {
- while ((readSize = reader.read(buffer, 0, bufferSize)) != EOF) {
- writer.write(buffer, 0, readSize);
- size += readSize;
- writer.flush();
- if (null != streamProgress) {
- streamProgress.progress(size);
- }
- }
- } catch (Exception e) {
- throw new IORuntimeException(e);
- }
- if (null != streamProgress) {
- streamProgress.finish();
- }
- return size;
+ return copy(reader, writer, bufferSize, -1, streamProgress);
+ }
+
+ /**
+ * 将Reader中的内容复制到Writer中,拷贝后不关闭Reader
+ *
+ * @param reader Reader
+ * @param writer Writer
+ * @param bufferSize 缓存大小
+ * @param streamProgress 进度处理器
+ * @return 传输的byte数
+ * @throws IORuntimeException IO异常
+ */
+ public static long copy(Reader reader, Writer writer, int bufferSize, int count, StreamProgress streamProgress) throws IORuntimeException {
+ return new ReaderWriterCopier(bufferSize, count, streamProgress).copy(reader, writer);
}
/**
@@ -146,33 +141,23 @@ public class IoUtil extends NioUtil {
* @throws IORuntimeException IO异常
*/
public static long copy(InputStream in, OutputStream out, int bufferSize, StreamProgress streamProgress) throws IORuntimeException {
- Assert.notNull(in, "InputStream is null !");
- Assert.notNull(out, "OutputStream is null !");
- if (bufferSize <= 0) {
- bufferSize = DEFAULT_BUFFER_SIZE;
- }
+ return copy(in, out, bufferSize, -1, streamProgress);
+ }
- byte[] buffer = new byte[bufferSize];
- if (null != streamProgress) {
- streamProgress.start();
- }
- long size = 0;
- try {
- for (int readSize; (readSize = in.read(buffer)) != EOF; ) {
- out.write(buffer, 0, readSize);
- size += readSize;
- if (null != streamProgress) {
- streamProgress.progress(size);
- }
- }
- out.flush();
- } catch (IOException e) {
- throw new IORuntimeException(e);
- }
- if (null != streamProgress) {
- streamProgress.finish();
- }
- return size;
+ /**
+ * 拷贝流,拷贝后不关闭流
+ *
+ * @param in 输入流
+ * @param out 输出流
+ * @param bufferSize 缓存大小
+ * @param count 总拷贝长度
+ * @param streamProgress 进度条
+ * @return 传输的byte数
+ * @throws IORuntimeException IO异常
+ * @since 5.7.8
+ */
+ public static long copy(InputStream in, OutputStream out, int bufferSize, int count, StreamProgress streamProgress) throws IORuntimeException {
+ return new StreamCopier(bufferSize, count, streamProgress).copy(in, out);
}
/**
@@ -390,14 +375,14 @@ public class IoUtil extends NioUtil {
*/
public static FastByteArrayOutputStream read(InputStream in, boolean isClose) throws IORuntimeException {
final FastByteArrayOutputStream out;
- if(in instanceof FileInputStream){
+ if (in instanceof FileInputStream) {
// 文件流的长度是可预见的,此时直接读取效率更高
try {
out = new FastByteArrayOutputStream(in.available());
} catch (IOException e) {
throw new IORuntimeException(e);
}
- } else{
+ } else {
out = new FastByteArrayOutputStream();
}
try {
@@ -434,7 +419,7 @@ public class IoUtil extends NioUtil {
final CharBuffer buffer = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
try {
while (-1 != reader.read(buffer)) {
- builder.append(buffer.flip().toString());
+ builder.append(buffer.flip());
}
} catch (IOException e) {
throw new IORuntimeException(e);
@@ -828,7 +813,7 @@ public class IoUtil extends NioUtil {
/**
* 转换为{@link BufferedInputStream}
*
- * @param in {@link InputStream}
+ * @param in {@link InputStream}
* @param bufferSize buffer size
* @return {@link BufferedInputStream}
* @since 5.6.1
@@ -853,7 +838,7 @@ public class IoUtil extends NioUtil {
/**
* 转换为{@link BufferedOutputStream}
*
- * @param out {@link OutputStream}
+ * @param out {@link OutputStream}
* @param bufferSize buffer size
* @return {@link BufferedOutputStream}
* @since 5.6.1
@@ -878,7 +863,7 @@ public class IoUtil extends NioUtil {
/**
* 转换为{@link BufferedReader}
*
- * @param reader {@link Reader}
+ * @param reader {@link Reader}
* @param bufferSize buffer size
* @return {@link BufferedReader}
* @since 5.6.1
@@ -903,7 +888,7 @@ public class IoUtil extends NioUtil {
/**
* 转换为{@link BufferedWriter}
*
- * @param writer {@link Writer}
+ * @param writer {@link Writer}
* @param bufferSize buffer size
* @return {@link BufferedWriter}
* @since 5.6.1
@@ -1291,7 +1276,7 @@ public class IoUtil extends NioUtil {
* while (it.hasNext()) {
* String line = it.nextLine();
* // do something with line
- * }
+ * }
* } finally {
* it.close();
* }
@@ -1301,7 +1286,7 @@ public class IoUtil extends NioUtil {
* @return {@link LineIter}
* @since 5.6.1
*/
- public static LineIter lineIter(Reader reader){
+ public static LineIter lineIter(Reader reader) {
return new LineIter(reader);
}
@@ -1314,18 +1299,18 @@ public class IoUtil extends NioUtil {
* while (it.hasNext()) {
* String line = it.nextLine();
* // do something with line
- * }
+ * }
* } finally {
* it.close();
* }
*
*
- * @param in {@link InputStream}
+ * @param in {@link InputStream}
* @param charset 编码
* @return {@link LineIter}
* @since 5.6.1
*/
- public static LineIter lineIter(InputStream in, Charset charset){
+ public static LineIter lineIter(InputStream in, Charset charset) {
return new LineIter(in, charset);
}
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/io/StreamProgress.java b/hutool-core/src/main/java/cn/hutool/core/io/StreamProgress.java
index 5e3a99559..96216200a 100644
--- a/hutool-core/src/main/java/cn/hutool/core/io/StreamProgress.java
+++ b/hutool-core/src/main/java/cn/hutool/core/io/StreamProgress.java
@@ -2,8 +2,8 @@ package cn.hutool.core.io;
/**
* Stream进度条
- * @author Looly
*
+ * @author Looly
*/
public interface StreamProgress {
@@ -14,6 +14,7 @@ public interface StreamProgress {
/**
* 进行中
+ *
* @param progressSize 已经进行的大小
*/
void progress(long progressSize);
diff --git a/hutool-core/src/main/java/cn/hutool/core/io/copy/IoCopier.java b/hutool-core/src/main/java/cn/hutool/core/io/copy/IoCopier.java
new file mode 100755
index 000000000..a80c5079f
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/io/copy/IoCopier.java
@@ -0,0 +1,60 @@
+package cn.hutool.core.io.copy;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.io.StreamProgress;
+
+/**
+ * IO拷贝抽象,可自定义包括缓存、进度条等信息
+ * 此对象非线程安全
+ *
+ * @param 拷贝源类型,如InputStream、Reader等
+ * @param 拷贝目标类型,如OutputStream、Writer等
+ * @author looly
+ * @since 5.7.8
+ */
+public abstract class IoCopier {
+
+ protected final int bufferSize;
+ /**
+ * 拷贝总数
+ */
+ protected final long count;
+
+ /**
+ * 进度条
+ */
+ protected StreamProgress progress;
+
+ /**
+ * 构造
+ *
+ * @param bufferSize 缓存大小,< 0 表示默认{@link IoUtil#DEFAULT_BUFFER_SIZE}
+ * @param count 拷贝总数
+ * @param progress 进度条
+ */
+ public IoCopier(int bufferSize, long count, StreamProgress progress) {
+ this.bufferSize = bufferSize > 0 ? bufferSize : IoUtil.DEFAULT_BUFFER_SIZE;
+ this.count = count;
+ this.progress = progress;
+ }
+
+ /**
+ * 执行拷贝
+ *
+ * @param source 拷贝源,如InputStream、Reader等
+ * @param target 拷贝目标,如OutputStream、Writer等
+ * @return 拷贝的实际长度
+ */
+ public abstract long copy(S source, T target);
+
+ /**
+ * 缓存大小,取默认缓存和目标长度最小值
+ * @return 缓存大小
+ */
+ protected int bufferSize(long count) {
+ if(count < 0){
+ count = Long.MAX_VALUE;
+ }
+ return Math.min(this.bufferSize, (int)count);
+ }
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/io/copy/ReaderWriterCopier.java b/hutool-core/src/main/java/cn/hutool/core/io/copy/ReaderWriterCopier.java
new file mode 100755
index 000000000..914cb5fce
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/io/copy/ReaderWriterCopier.java
@@ -0,0 +1,114 @@
+package cn.hutool.core.io.copy;
+
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.io.StreamProgress;
+import cn.hutool.core.lang.Assert;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * {@link Reader} 向 {@link Writer} 拷贝
+ *
+ * @author looly
+ * @since 5.7.8
+ */
+public class ReaderWriterCopier extends IoCopier {
+
+ /**
+ * 构造
+ */
+ public ReaderWriterCopier() {
+ this(IoUtil.DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * 构造
+ *
+ * @param bufferSize 缓存大小
+ */
+ public ReaderWriterCopier(int bufferSize) {
+ this(bufferSize, -1);
+ }
+
+ /**
+ * 构造
+ *
+ * @param bufferSize 缓存大小
+ * @param count 拷贝总数
+ */
+ public ReaderWriterCopier(int bufferSize, long count) {
+ this(bufferSize, count, null);
+ }
+
+ /**
+ * 构造
+ *
+ * @param bufferSize 缓存大小
+ * @param count 拷贝总数
+ * @param progress 进度条
+ */
+ public ReaderWriterCopier(int bufferSize, long count, StreamProgress progress) {
+ super(bufferSize, count, progress);
+ }
+
+ @Override
+ public long copy(Reader source, Writer target) {
+ Assert.notNull(source, "InputStream is null !");
+ Assert.notNull(target, "OutputStream is null !");
+
+ final StreamProgress progress = this.progress;
+ if (null != progress) {
+ progress.start();
+ }
+ final long size;
+ try {
+ size = doCopy(source, target, new char[bufferSize(this.count)], progress);
+ target.flush();
+ } catch (IOException e) {
+ throw new IORuntimeException(e);
+ }
+
+ if (null != progress) {
+ progress.finish();
+ }
+ return size;
+ }
+
+ /**
+ * 执行拷贝,如果限制最大长度,则按照最大长度读取,否则一直读取直到遇到-1
+ *
+ * @param source {@link InputStream}
+ * @param target {@link OutputStream}
+ * @param buffer 缓存
+ * @param progress 进度条
+ * @return 拷贝总长度
+ * @throws IOException IO异常
+ */
+ private long doCopy(Reader source, Writer target, char[] buffer, StreamProgress progress) throws IOException {
+ long numToRead = this.count > 0 ? this.count : Long.MAX_VALUE;
+ long total = 0;
+
+ int read;
+ while (numToRead > 0) {
+ read = source.read(buffer, 0, bufferSize(numToRead));
+ if (read < 0) {
+ // 提前读取到末尾
+ break;
+ }
+ target.write(buffer, 0, read);
+
+ numToRead -= read;
+ total += read;
+ if (null != progress) {
+ progress.progress(total);
+ }
+ }
+
+ return total;
+ }
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/io/copy/StreamCopier.java b/hutool-core/src/main/java/cn/hutool/core/io/copy/StreamCopier.java
new file mode 100755
index 000000000..35a3a53a7
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/io/copy/StreamCopier.java
@@ -0,0 +1,112 @@
+package cn.hutool.core.io.copy;
+
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.io.StreamProgress;
+import cn.hutool.core.lang.Assert;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * {@link InputStream} 向 {@link OutputStream} 拷贝
+ *
+ * @author looly
+ * @since 5.7.8
+ */
+public class StreamCopier extends IoCopier {
+
+ /**
+ * 构造
+ */
+ public StreamCopier() {
+ this(IoUtil.DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * 构造
+ *
+ * @param bufferSize 缓存大小
+ */
+ public StreamCopier(int bufferSize) {
+ this(bufferSize, -1);
+ }
+
+ /**
+ * 构造
+ *
+ * @param bufferSize 缓存大小
+ * @param count 拷贝总数
+ */
+ public StreamCopier(int bufferSize, long count) {
+ this(bufferSize, count, null);
+ }
+
+ /**
+ * 构造
+ *
+ * @param bufferSize 缓存大小
+ * @param count 拷贝总数
+ * @param progress 进度条
+ */
+ public StreamCopier(int bufferSize, long count, StreamProgress progress) {
+ super(bufferSize, count, progress);
+ }
+
+ @Override
+ public long copy(InputStream source, OutputStream target) {
+ Assert.notNull(source, "InputStream is null !");
+ Assert.notNull(target, "OutputStream is null !");
+
+ final StreamProgress progress = this.progress;
+ if (null != progress) {
+ progress.start();
+ }
+ final long size;
+ try {
+ size = doCopy(source, target, new byte[bufferSize(this.count)], progress);
+ target.flush();
+ } catch (IOException e) {
+ throw new IORuntimeException(e);
+ }
+
+ if (null != progress) {
+ progress.finish();
+ }
+ return size;
+ }
+
+ /**
+ * 执行拷贝,如果限制最大长度,则按照最大长度读取,否则一直读取直到遇到-1
+ *
+ * @param source {@link InputStream}
+ * @param target {@link OutputStream}
+ * @param buffer 缓存
+ * @param progress 进度条
+ * @return 拷贝总长度
+ * @throws IOException IO异常
+ */
+ private long doCopy(InputStream source, OutputStream target, byte[] buffer, StreamProgress progress) throws IOException {
+ long numToRead = this.count > 0 ? this.count : Long.MAX_VALUE;
+ long total = 0;
+
+ int read;
+ while (numToRead > 0) {
+ read = source.read(buffer, 0, bufferSize(numToRead));
+ if (read < 0) {
+ // 提前读取到末尾
+ break;
+ }
+ target.write(buffer, 0, read);
+
+ numToRead -= read;
+ total += read;
+ if (null != progress) {
+ progress.progress(total);
+ }
+ }
+
+ return total;
+ }
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/io/copy/package-info.java b/hutool-core/src/main/java/cn/hutool/core/io/copy/package-info.java
new file mode 100755
index 000000000..a544b5626
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/io/copy/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * IO流拷贝相关封装相关封装
+ *
+ * @author looly
+ * @since 5.7.8
+ */
+package cn.hutool.core.io.copy;
diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Snowflake.java b/hutool-core/src/main/java/cn/hutool/core/lang/Snowflake.java
index 63f7897d9..1ba75e310 100644
--- a/hutool-core/src/main/java/cn/hutool/core/lang/Snowflake.java
+++ b/hutool-core/src/main/java/cn/hutool/core/lang/Snowflake.java
@@ -78,8 +78,7 @@ public class Snowflake implements Serializable {
* 构造,使用自动生成的工作节点ID和数据中心ID
*/
public Snowflake() {
- this(IdUtil.getWorkerId(IdUtil.getDataCenterId(MAX_DATA_CENTER_ID), MAX_WORKER_ID)
- , IdUtil.getDataCenterId(MAX_DATA_CENTER_ID));
+ this(IdUtil.getWorkerId(IdUtil.getDataCenterId(MAX_DATA_CENTER_ID), MAX_WORKER_ID));
}
/**
diff --git a/hutool-core/src/main/java/cn/hutool/core/net/DefaultTrustManager.java b/hutool-core/src/main/java/cn/hutool/core/net/DefaultTrustManager.java
index b9cb7d88c..65b112564 100644
--- a/hutool-core/src/main/java/cn/hutool/core/net/DefaultTrustManager.java
+++ b/hutool-core/src/main/java/cn/hutool/core/net/DefaultTrustManager.java
@@ -14,6 +14,12 @@ import java.security.cert.X509Certificate;
*/
public class DefaultTrustManager extends X509ExtendedTrustManager {
+ /**
+ * 默认的全局单例默认信任管理器,,默认信任所有客户端和服务端证书
+ * @since 5.7.8
+ */
+ public static DefaultTrustManager INSTANCE = new DefaultTrustManager();
+
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
diff --git a/hutool-core/src/main/java/cn/hutool/core/net/SSLContextBuilder.java b/hutool-core/src/main/java/cn/hutool/core/net/SSLContextBuilder.java
index 6c780c5ee..8a0efced2 100644
--- a/hutool-core/src/main/java/cn/hutool/core/net/SSLContextBuilder.java
+++ b/hutool-core/src/main/java/cn/hutool/core/net/SSLContextBuilder.java
@@ -13,46 +13,24 @@ import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
- * {@link SSLContext}构建器
+ * {@link SSLContext}构建器,可以自定义:
+ *
+ * - 协议(protocol),默认TLS
+ * - {@link KeyManager},默认空
+ * - {@link TrustManager},默认{@link DefaultTrustManager},即信任全部
+ * - {@link SecureRandom}
+ *
+ *
+ * 构建后可获得{@link SSLContext},通过调用{@link SSLContext#getSocketFactory()}获取{@link javax.net.ssl.SSLSocketFactory}
*
* @author Looly
* @since 5.5.2
*/
-public class SSLContextBuilder {
-
- /**
- * Supports some version of SSL; may support other versions
- */
- public static final String SSL = "SSL";
- /**
- * Supports SSL version 2 or later; may support other versions
- */
- public static final String SSLv2 = "SSLv2";
- /**
- * Supports SSL version 3; may support other versions
- */
- public static final String SSLv3 = "SSLv3";
-
- /**
- * Supports some version of TLS; may support other versions
- */
- public static final String TLS = "TLS";
- /**
- * Supports RFC 2246: TLS version 1.0 ; may support other versions
- */
- public static final String TLSv1 = "TLSv1";
- /**
- * Supports RFC 4346: TLS version 1.1 ; may support other versions
- */
- public static final String TLSv11 = "TLSv1.1";
- /**
- * Supports RFC 5246: TLS version 1.2 ; may support other versions
- */
- public static final String TLSv12 = "TLSv1.2";
+public class SSLContextBuilder implements SSLProtocols {
private String protocol = TLS;
private KeyManager[] keyManagers;
- private TrustManager[] trustManagers = {new DefaultTrustManager()};
+ private TrustManager[] trustManagers = {DefaultTrustManager.INSTANCE};
private SecureRandom secureRandom = new SecureRandom();
@@ -136,7 +114,7 @@ public class SSLContextBuilder {
* @return {@link SSLContext}
* @throws IORuntimeException 包装 GeneralSecurityException异常
*/
- public SSLContext buildQuietly() throws IORuntimeException{
+ public SSLContext buildQuietly() throws IORuntimeException {
try {
return build();
} catch (GeneralSecurityException e) {
diff --git a/hutool-core/src/main/java/cn/hutool/core/net/SSLProtocols.java b/hutool-core/src/main/java/cn/hutool/core/net/SSLProtocols.java
new file mode 100755
index 000000000..32e938f9f
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/net/SSLProtocols.java
@@ -0,0 +1,40 @@
+package cn.hutool.core.net;
+
+/**
+ * SSL或TLS协议
+ *
+ * @author looly
+ * @since 5.7.8
+ */
+public interface SSLProtocols {
+
+ /**
+ * Supports some version of SSL; may support other versions
+ */
+ String SSL = "SSL";
+ /**
+ * Supports SSL version 2 or later; may support other versions
+ */
+ String SSLv2 = "SSLv2";
+ /**
+ * Supports SSL version 3; may support other versions
+ */
+ String SSLv3 = "SSLv3";
+
+ /**
+ * Supports some version of TLS; may support other versions
+ */
+ String TLS = "TLS";
+ /**
+ * Supports RFC 2246: TLS version 1.0 ; may support other versions
+ */
+ String TLSv1 = "TLSv1";
+ /**
+ * Supports RFC 4346: TLS version 1.1 ; may support other versions
+ */
+ String TLSv11 = "TLSv1.1";
+ /**
+ * Supports RFC 5246: TLS version 1.2 ; may support other versions
+ */
+ String TLSv12 = "TLSv1.2";
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/net/SSLUtil.java b/hutool-core/src/main/java/cn/hutool/core/net/SSLUtil.java
index ea7d686d2..8519f94e0 100644
--- a/hutool-core/src/main/java/cn/hutool/core/net/SSLUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/net/SSLUtil.java
@@ -14,6 +14,18 @@ import javax.net.ssl.TrustManager;
*/
public class SSLUtil {
+ /**
+ * 创建{@link SSLContext},默认新人全部
+ *
+ * @param protocol SSL协议,例如TLS等
+ * @return {@link SSLContext}
+ * @throws IORuntimeException 包装 GeneralSecurityException异常
+ * @since 5.7.8
+ */
+ public static SSLContext createSSLContext(String protocol) throws IORuntimeException{
+ return SSLContextBuilder.create().setProtocol(protocol).buildQuietly();
+ }
+
/**
* 创建{@link SSLContext}
*
diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java
index ca76e651c..20946d124 100644
--- a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java
+++ b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java
@@ -10,6 +10,7 @@ import cn.hutool.core.io.resource.MultiFileResource;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.net.SSLUtil;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -887,11 +888,7 @@ public class HttpRequest extends HttpBase {
*/
public HttpRequest setSSLProtocol(String protocol) {
Assert.notBlank(protocol, "protocol must be not blank!");
- try {
- setSSLSocketFactory(SSLSocketFactoryBuilder.create().setProtocol(protocol).build());
- } catch (Exception e) {
- throw new HttpException(e);
- }
+ setSSLSocketFactory(SSLUtil.createSSLContext(protocol).getSocketFactory());
return this;
}
diff --git a/hutool-http/src/main/java/cn/hutool/http/ssl/AndroidSupportSSLFactory.java b/hutool-http/src/main/java/cn/hutool/http/ssl/AndroidSupportSSLFactory.java
index fae1ddfcb..bfcf02c4a 100644
--- a/hutool-http/src/main/java/cn/hutool/http/ssl/AndroidSupportSSLFactory.java
+++ b/hutool-http/src/main/java/cn/hutool/http/ssl/AndroidSupportSSLFactory.java
@@ -1,12 +1,7 @@
package cn.hutool.http.ssl;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-
-import static cn.hutool.http.ssl.SSLSocketFactoryBuilder.SSLv3;
-import static cn.hutool.http.ssl.SSLSocketFactoryBuilder.TLSv1;
-import static cn.hutool.http.ssl.SSLSocketFactoryBuilder.TLSv11;
-import static cn.hutool.http.ssl.SSLSocketFactoryBuilder.TLSv12;
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.net.SSLProtocols;
/**
* 兼容android低版本SSL连接
@@ -20,10 +15,11 @@ import static cn.hutool.http.ssl.SSLSocketFactoryBuilder.TLSv12;
public class AndroidSupportSSLFactory extends CustomProtocolsSSLFactory {
// Android低版本不重置的话某些SSL访问就会失败
- private static final String[] protocols = {SSLv3, TLSv1, TLSv11, TLSv12};
+ private static final String[] protocols = {
+ SSLProtocols.SSLv3, SSLProtocols.TLSv1, SSLProtocols.TLSv11, SSLProtocols.TLSv12};
- public AndroidSupportSSLFactory() throws KeyManagementException, NoSuchAlgorithmException {
+ public AndroidSupportSSLFactory() throws IORuntimeException {
super(protocols);
}
-}
\ No newline at end of file
+}
diff --git a/hutool-http/src/main/java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java b/hutool-http/src/main/java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java
index 4d512614c..ab9df8e79 100644
--- a/hutool-http/src/main/java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java
+++ b/hutool-http/src/main/java/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java
@@ -1,5 +1,7 @@
package cn.hutool.http.ssl;
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.net.SSLUtil;
import cn.hutool.core.util.ArrayUtil;
import javax.net.ssl.SSLSocket;
@@ -7,8 +9,6 @@ import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
/**
* 自定义支持协议类型的SSLSocketFactory
@@ -24,12 +24,11 @@ public class CustomProtocolsSSLFactory extends SSLSocketFactory {
* 构造
*
* @param protocols 支持协议列表
- * @throws KeyManagementException KeyManagementException
- * @throws NoSuchAlgorithmException 无此算法
+ * @throws IORuntimeException IO异常
*/
- public CustomProtocolsSSLFactory(String... protocols) throws KeyManagementException, NoSuchAlgorithmException {
+ public CustomProtocolsSSLFactory(String... protocols) throws IORuntimeException {
this.protocols = protocols;
- this.base = SSLSocketFactoryBuilder.create().build();
+ this.base = SSLUtil.createSSLContext(null).getSocketFactory();
}
@Override
@@ -90,7 +89,7 @@ public class CustomProtocolsSSLFactory extends SSLSocketFactory {
* @param socket SSLSocket
*/
private void resetProtocols(SSLSocket socket) {
- if(ArrayUtil.isNotEmpty(this.protocols)){
+ if (ArrayUtil.isNotEmpty(this.protocols)) {
socket.setEnabledProtocols(this.protocols);
}
}
diff --git a/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java b/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java
index 7f9d06b98..80e27794a 100644
--- a/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java
+++ b/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLFactory.java
@@ -1,8 +1,5 @@
package cn.hutool.http.ssl;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-
/**
* 默认的SSLSocketFactory
*
@@ -11,7 +8,7 @@ import java.security.NoSuchAlgorithmException;
*/
public class DefaultSSLFactory extends CustomProtocolsSSLFactory {
- public DefaultSSLFactory() throws KeyManagementException, NoSuchAlgorithmException {
+ public DefaultSSLFactory() {
}
-}
\ No newline at end of file
+}
diff --git a/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLInfo.java b/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLInfo.java
index 7afc6b50c..a5b7a9708 100644
--- a/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLInfo.java
+++ b/hutool-http/src/main/java/cn/hutool/http/ssl/DefaultSSLInfo.java
@@ -1,14 +1,11 @@
package cn.hutool.http.ssl;
import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.HttpException;
import javax.net.ssl.SSLSocketFactory;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
/**
- * 默认的SSL配置,当用户未设置相关信息时,使用默认设置,默认设置为单例模式。
+ * 默认的全局SSL配置,当用户未设置相关信息时,使用默认设置,默认设置为单例模式。
*
* @author looly
* @since 5.1.2
@@ -25,16 +22,11 @@ public class DefaultSSLInfo {
static {
TRUST_ANY_HOSTNAME_VERIFIER = new TrustAnyHostnameVerifier();
-
- try {
- if (StrUtil.equalsIgnoreCase("dalvik", System.getProperty("java.vm.name"))) {
- // 兼容android低版本SSL连接
- DEFAULT_SSF = new AndroidSupportSSLFactory();
- } else {
- DEFAULT_SSF = new DefaultSSLFactory();
- }
- } catch (KeyManagementException | NoSuchAlgorithmException e) {
- throw new HttpException(e);
+ if (StrUtil.equalsIgnoreCase("dalvik", System.getProperty("java.vm.name"))) {
+ // 兼容android低版本SSL连接
+ DEFAULT_SSF = new AndroidSupportSSLFactory();
+ } else {
+ DEFAULT_SSF = new DefaultSSLFactory();
}
}
}
diff --git a/hutool-http/src/main/java/cn/hutool/http/ssl/SSLSocketFactoryBuilder.java b/hutool-http/src/main/java/cn/hutool/http/ssl/SSLSocketFactoryBuilder.java
index 8efb68bd3..bc94c8a1e 100644
--- a/hutool-http/src/main/java/cn/hutool/http/ssl/SSLSocketFactoryBuilder.java
+++ b/hutool-http/src/main/java/cn/hutool/http/ssl/SSLSocketFactoryBuilder.java
@@ -1,6 +1,7 @@
package cn.hutool.http.ssl;
import cn.hutool.core.net.SSLContextBuilder;
+import cn.hutool.core.net.SSLProtocols;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLSocketFactory;
@@ -14,38 +15,10 @@ import java.security.SecureRandom;
*
* @author Looly
* @see SSLContextBuilder
+ * @deprecated 请使用 {@link SSLContextBuilder}
*/
-public class SSLSocketFactoryBuilder {
-
- /**
- * Supports some version of SSL; may support other versions
- */
- public static final String SSL = SSLContextBuilder.SSL;
- /**
- * Supports SSL version 2 or later; may support other versions
- */
- public static final String SSLv2 = SSLContextBuilder.SSLv2;
- /**
- * Supports SSL version 3; may support other versions
- */
- public static final String SSLv3 = SSLContextBuilder.SSLv3;
-
- /**
- * Supports some version of TLS; may support other versions
- */
- public static final String TLS = SSLContextBuilder.TLS;
- /**
- * Supports RFC 2246: TLS version 1.0 ; may support other versions
- */
- public static final String TLSv1 = SSLContextBuilder.TLSv1;
- /**
- * Supports RFC 4346: TLS version 1.1 ; may support other versions
- */
- public static final String TLSv11 = SSLContextBuilder.TLSv11;
- /**
- * Supports RFC 5246: TLS version 1.2 ; may support other versions
- */
- public static final String TLSv12 = SSLContextBuilder.TLSv12;
+@Deprecated
+public class SSLSocketFactoryBuilder implements SSLProtocols {
SSLContextBuilder sslContextBuilder;
diff --git a/hutool-http/src/test/java/cn/hutool/http/HttpRequestTest.java b/hutool-http/src/test/java/cn/hutool/http/HttpRequestTest.java
index eef2daac3..2aabe1afe 100644
--- a/hutool-http/src/test/java/cn/hutool/http/HttpRequestTest.java
+++ b/hutool-http/src/test/java/cn/hutool/http/HttpRequestTest.java
@@ -3,8 +3,8 @@ package cn.hutool.http;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.lang.Console;
+import cn.hutool.core.net.SSLProtocols;
import cn.hutool.core.util.CharsetUtil;
-import cn.hutool.http.ssl.SSLSocketFactoryBuilder;
import org.junit.Ignore;
import org.junit.Test;
@@ -98,7 +98,7 @@ public class HttpRequestTest {
// 禁用缓存
.disableCache()
// 自定义SSL版本
- .setSSLProtocol(SSLSocketFactoryBuilder.TLSv12);
+ .setSSLProtocol(SSLProtocols.TLSv12);
Console.log(request.execute().body());
}