From c54f2a154ada1509d6cc5f98520ad647e455531e Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 11 Aug 2021 23:30:47 +0800 Subject: [PATCH] add IoCopier --- CHANGELOG.md | 1 + .../main/java/cn/hutool/core/io/IoUtil.java | 105 +++++++--------- .../cn/hutool/core/io/StreamProgress.java | 3 +- .../java/cn/hutool/core/io/copy/IoCopier.java | 60 +++++++++ .../core/io/copy/ReaderWriterCopier.java | 114 ++++++++++++++++++ .../cn/hutool/core/io/copy/StreamCopier.java | 112 +++++++++++++++++ .../cn/hutool/core/io/copy/package-info.java | 7 ++ .../java/cn/hutool/core/lang/Snowflake.java | 3 +- .../hutool/core/net/DefaultTrustManager.java | 6 + .../cn/hutool/core/net/SSLContextBuilder.java | 46 ++----- .../java/cn/hutool/core/net/SSLProtocols.java | 40 ++++++ .../main/java/cn/hutool/core/net/SSLUtil.java | 12 ++ .../main/java/cn/hutool/http/HttpRequest.java | 7 +- .../http/ssl/AndroidSupportSSLFactory.java | 16 +-- .../http/ssl/CustomProtocolsSSLFactory.java | 13 +- .../cn/hutool/http/ssl/DefaultSSLFactory.java | 7 +- .../cn/hutool/http/ssl/DefaultSSLInfo.java | 20 +-- .../http/ssl/SSLSocketFactoryBuilder.java | 35 +----- .../java/cn/hutool/http/HttpRequestTest.java | 4 +- 19 files changed, 440 insertions(+), 171 deletions(-) create mode 100755 hutool-core/src/main/java/cn/hutool/core/io/copy/IoCopier.java create mode 100755 hutool-core/src/main/java/cn/hutool/core/io/copy/ReaderWriterCopier.java create mode 100755 hutool-core/src/main/java/cn/hutool/core/io/copy/StreamCopier.java create mode 100755 hutool-core/src/main/java/cn/hutool/core/io/copy/package-info.java create mode 100755 hutool-core/src/main/java/cn/hutool/core/net/SSLProtocols.java 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()); }