diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java index c1cc7265a..e96857acd 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java @@ -58,7 +58,7 @@ import java.util.regex.Pattern; * * @author looly */ -public class FileUtil extends PathUtil { +public class FileUtil { /** * 文件路径分隔符
@@ -146,7 +146,7 @@ public class FileUtil extends PathUtil { * @return 是否为空 */ public static boolean isDirEmpty(final File dir) { - return isDirEmpty(dir.toPath()); + return PathUtil.isDirEmpty(dir.toPath()); } // region ----- loop and walk @@ -187,7 +187,7 @@ public class FileUtil extends PathUtil { * @since 4.6.3 */ public static List loopFiles(final File file, final int maxDepth, final FileFilter fileFilter) { - return loopFiles(file.toPath(), maxDepth, fileFilter); + return PathUtil.loopFiles(file.toPath(), maxDepth, fileFilter); } /** @@ -739,7 +739,7 @@ public class FileUtil extends PathUtil { */ public static void del(final File file) throws IORuntimeException { Assert.notNull(file, "File must be not null!"); - del(file.toPath()); + PathUtil.del(file.toPath()); } /** @@ -764,7 +764,7 @@ public class FileUtil extends PathUtil { */ public static void clean(final File directory) throws IORuntimeException { Assert.notNull(directory, "File must be not null!"); - clean(directory.toPath()); + PathUtil.clean(directory.toPath()); } /** @@ -991,7 +991,7 @@ public class FileUtil extends PathUtil { public static File copy(final Resource src, final File target, final boolean isOverride) throws IORuntimeException { Assert.notNull(src, "Src file must be not null!"); Assert.notNull(target, "target file must be not null!"); - return copy( + return PathUtil.copy( src, target.toPath(), isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{}) @@ -1012,7 +1012,7 @@ public class FileUtil extends PathUtil { // check Assert.notNull(src, "Source File is null !"); Assert.notNull(target, "Target File or directory is null !"); - return copy(src, target.toPath(), options).toFile(); + return PathUtil.copy(src, target.toPath(), options).toFile(); } /** @@ -1028,7 +1028,7 @@ public class FileUtil extends PathUtil { // check Assert.notNull(src, "Source File is null !"); Assert.notNull(out, "Target stream is null !"); - return copy(src.toPath(), out); + return PathUtil.copy(src.toPath(), out); } /** @@ -1064,7 +1064,7 @@ public class FileUtil extends PathUtil { public static File copy(final File src, final File target, final boolean isOverride) throws IORuntimeException { Assert.notNull(src, "Src file must be not null!"); Assert.notNull(target, "target file must be not null!"); - return copy( + return PathUtil.copy( src.toPath(), target.toPath(), isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{}) @@ -1090,7 +1090,7 @@ public class FileUtil extends PathUtil { public static File copyContent(final File src, final File target, final boolean isOverride) throws IORuntimeException { Assert.notNull(src, "Src file must be not null!"); Assert.notNull(target, "target file must be not null!"); - return copyContent( + return PathUtil.copyContent( src.toPath(), target.toPath(), isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{}) @@ -1119,7 +1119,7 @@ public class FileUtil extends PathUtil { public static File move(final File src, final File target, final boolean isOverride) throws IORuntimeException { Assert.notNull(src, "Src file must be not null!"); Assert.notNull(target, "target file must be not null!"); - return move(src.toPath(), target.toPath(), isOverride).toFile(); + return PathUtil.move(src.toPath(), target.toPath(), isOverride).toFile(); } /** @@ -1170,7 +1170,7 @@ public class FileUtil extends PathUtil { newName = newName.concat(".").concat(extName); } } - return rename(file.toPath(), newName, isOverride).toFile(); + return PathUtil.rename(file.toPath(), newName, isOverride).toFile(); } // region ----- getCanonicalPath and getAbsolutePath @@ -1758,7 +1758,7 @@ public class FileUtil extends PathUtil { if (null == file) { return null; } - return readBytes(file.toPath()); + return PathUtil.readBytes(file.toPath()); } /** @@ -2170,7 +2170,7 @@ public class FileUtil extends PathUtil { * @throws IORuntimeException IO异常 */ public static BufferedOutputStream getOutputStream(final String path, final OpenOption... options) throws IORuntimeException { - return getOutputStream(touch(path)); + return getOutputStream(touch(path), options); } /** @@ -2809,7 +2809,7 @@ public class FileUtil extends PathUtil { String contentType = URLConnection.getFileNameMap().getContentTypeFor(filePath); if (null == contentType) { - contentType = getMimeType(Paths.get(filePath)); + contentType = PathUtil.getMimeType(Paths.get(filePath)); } return contentType; @@ -2823,7 +2823,7 @@ public class FileUtil extends PathUtil { * @since 4.4.2 */ public static boolean isSymlink(final File file) { - return isSymlink(file.toPath()); + return PathUtil.isSymlink(file.toPath()); } /** @@ -2837,7 +2837,7 @@ public class FileUtil extends PathUtil { public static boolean isSub(final File parent, final File sub) { Assert.notNull(parent); Assert.notNull(sub); - return isSub(parent.toPath(), sub.toPath()); + return PathUtil.isSub(parent.toPath(), sub.toPath()); } /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/watch/WatchMonitor.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/watch/WatchMonitor.java index 0550e26ad..11afebbbb 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/io/watch/WatchMonitor.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/watch/WatchMonitor.java @@ -16,7 +16,6 @@ package org.dromara.hutool.core.io.watch; -import org.dromara.hutool.core.io.file.FileUtil; import org.dromara.hutool.core.io.file.PathUtil; import org.dromara.hutool.core.io.watch.watchers.WatcherChain; import org.dromara.hutool.core.text.CharUtil; @@ -172,7 +171,7 @@ public class WatchMonitor extends Thread implements Closeable, Serializable { //获取目录或文件路径 if (!PathUtil.exists(this.dir, false)) { // 不存在的路径 - final Path lastPathEle = FileUtil.getLastPathEle(this.dir); + final Path lastPathEle = PathUtil.getLastPathEle(this.dir); if (null != lastPathEle) { final String lastPathEleStr = lastPathEle.toString(); //带有点表示有扩展名,按照未创建的文件对待。Linux下.d的为目录,排除之 diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java index 5f1aadbef..9eeccb07a 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java @@ -814,7 +814,7 @@ public class BeanUtilTest { testPojo.setTestPojo2List(new TestPojo2[]{testPojo2, testPojo3}); - final BeanPath beanPath = BeanPath.of("testPojo2List.age"); + final BeanPath beanPath = BeanPath.of("testPojo2List.age"); final Object o = beanPath.getValue(testPojo); assertEquals(Integer.valueOf(2), ArrayUtil.get(o, 0)); diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/io/file/FileUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/io/file/FileUtilTest.java index b6115cf86..8ec20bb6b 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/io/file/FileUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/io/file/FileUtilTest.java @@ -27,8 +27,6 @@ import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.JRE; import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -197,28 +195,6 @@ public class FileUtilTest { Assertions.assertEquals(normalize, normalize2); } - @Test - public void subPathTest() { - final Path path = Paths.get("/aaa/bbb/ccc/ddd/eee/fff"); - - Path subPath = FileUtil.subPath(path, 5, 4); - Assertions.assertEquals("eee", subPath.toString()); - subPath = FileUtil.subPath(path, 0, 1); - Assertions.assertEquals("aaa", subPath.toString()); - subPath = FileUtil.subPath(path, 1, 0); - Assertions.assertEquals("aaa", subPath.toString()); - - // 负数 - subPath = FileUtil.subPath(path, -1, 0); - Assertions.assertEquals("aaa/bbb/ccc/ddd/eee", subPath.toString().replace('\\', '/')); - subPath = FileUtil.subPath(path, -1, Integer.MAX_VALUE); - Assertions.assertEquals("fff", subPath.toString()); - subPath = FileUtil.subPath(path, -1, path.getNameCount()); - Assertions.assertEquals("fff", subPath.toString()); - subPath = FileUtil.subPath(path, -2, -3); - Assertions.assertEquals("ddd", subPath.toString()); - } - @Test public void subPathTest2() { String subPath = FileUtil.subPath("d:/aaa/bbb/", "d:/aaa/bbb/ccc/"); @@ -243,20 +219,6 @@ public class FileUtilTest { Assertions.assertEquals("", subPath); } - @Test - public void getPathEle() { - final Path path = Paths.get("/aaa/bbb/ccc/ddd/eee/fff"); - - Path ele = FileUtil.getPathEle(path, -1); - Assertions.assertEquals("fff", ele.toString()); - ele = FileUtil.getPathEle(path, 0); - Assertions.assertEquals("aaa", ele.toString()); - ele = FileUtil.getPathEle(path, -5); - Assertions.assertEquals("bbb", ele.toString()); - ele = FileUtil.getPathEle(path, -6); - Assertions.assertEquals("aaa", ele.toString()); - } - @Test @EnabledForJreRange(max = JRE.JAVA_8) public void listFileNamesTest() { diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/io/file/PathUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/io/file/PathUtilTest.java index d1af78cfe..8dcfc009e 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/io/file/PathUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/io/file/PathUtilTest.java @@ -164,4 +164,40 @@ public class PathUtilTest { assertTrue(PathUtil.isSameFile(srcFile.toPath(), destFile.toPath())); } + + @Test + public void subPathTest() { + final Path path = Paths.get("/aaa/bbb/ccc/ddd/eee/fff"); + + Path subPath = PathUtil.subPath(path, 5, 4); + Assertions.assertEquals("eee", subPath.toString()); + subPath = PathUtil.subPath(path, 0, 1); + Assertions.assertEquals("aaa", subPath.toString()); + subPath = PathUtil.subPath(path, 1, 0); + Assertions.assertEquals("aaa", subPath.toString()); + + // 负数 + subPath = PathUtil.subPath(path, -1, 0); + Assertions.assertEquals("aaa/bbb/ccc/ddd/eee", subPath.toString().replace('\\', '/')); + subPath = PathUtil.subPath(path, -1, Integer.MAX_VALUE); + Assertions.assertEquals("fff", subPath.toString()); + subPath = PathUtil.subPath(path, -1, path.getNameCount()); + Assertions.assertEquals("fff", subPath.toString()); + subPath = PathUtil.subPath(path, -2, -3); + Assertions.assertEquals("ddd", subPath.toString()); + } + + @Test + public void getPathEleTest() { + final Path path = Paths.get("/aaa/bbb/ccc/ddd/eee/fff"); + + Path ele = PathUtil.getPathEle(path, -1); + assertEquals("fff", ele.toString()); + ele = PathUtil.getPathEle(path, 0); + assertEquals("aaa", ele.toString()); + ele = PathUtil.getPathEle(path, -5); + assertEquals("bbb", ele.toString()); + ele = PathUtil.getPathEle(path, -6); + assertEquals("aaa", ele.toString()); + } } diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java index 7f7806bad..544cdcc99 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java @@ -28,7 +28,6 @@ import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; -import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; import org.apache.hc.core5.http.ClassicHttpRequest; import org.apache.hc.core5.http.Header; import org.apache.hc.core5.http.HttpHost; @@ -203,11 +202,17 @@ public class HttpClient5Engine extends AbstractClientEngine { // SSL配置 final SSLInfo sslInfo = config.getSslInfo(); if (null != sslInfo) { - connectionManagerBuilder.setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create() - .setTlsVersions(sslInfo.getProtocols()) +// connectionManagerBuilder.setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create() +// .setTlsVersions(sslInfo.getProtocols()) +// .setSslContext(sslInfo.getSslContext()) +// .setHostnameVerifier(sslInfo.getHostnameVerifier()) +// .build()); + connectionManagerBuilder.setTlsSocketStrategy(TlsSocketStrategyBuilder.of() .setSslContext(sslInfo.getSslContext()) + .setSupportedProtocols(sslInfo.getProtocols()) .setHostnameVerifier(sslInfo.getHostnameVerifier()) - .build()); + .build() + ); } // 连接超时配置 final int connectionTimeout = config.getConnectionTimeout(); diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/TlsSocketStrategyBuilder.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/TlsSocketStrategyBuilder.java new file mode 100644 index 000000000..497199235 --- /dev/null +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/TlsSocketStrategyBuilder.java @@ -0,0 +1,133 @@ +/* + * 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.ssl.DefaultClientTlsStrategy; +import org.apache.hc.client5.http.ssl.HostnameVerificationPolicy; +import org.apache.hc.client5.http.ssl.HttpsSupport; +import org.apache.hc.client5.http.ssl.TlsSocketStrategy; +import org.apache.hc.core5.reactor.ssl.SSLBufferMode; +import org.apache.hc.core5.ssl.SSLContexts; +import org.dromara.hutool.core.lang.builder.Builder; +import org.dromara.hutool.core.util.ObjUtil; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; + +/** + * TLS Socket 策略构建器 + * + * @author looly + * @since 6.0.0 + */ +public class TlsSocketStrategyBuilder implements Builder { + private static final long serialVersionUID = 1L; + + /** + * 创建TLS Socket策略构建器 + * + * @return TlsSocketStrategyBuilder + */ + public static TlsSocketStrategyBuilder of() { + return new TlsSocketStrategyBuilder(); + } + + private SSLContext sslContext; + private String[] supportedProtocols; + private String[] supportedCipherSuites; + private SSLBufferMode sslBufferMode; + private HostnameVerificationPolicy hostnameVerificationPolicy; + private HostnameVerifier hostnameVerifier; + + /** + * 设置SSL上下文 + * + * @param sslContext SSL上下文 + * @return this + */ + public TlsSocketStrategyBuilder setSslContext(final SSLContext sslContext) { + this.sslContext = sslContext; + return this; + } + + /** + * 设置支持的协议版本 + * + * @param supportedProtocols 支持的协议版本 + * @return this + */ + public TlsSocketStrategyBuilder setSupportedProtocols(final String[] supportedProtocols) { + this.supportedProtocols = supportedProtocols; + return this; + } + + /** + * 设置支持的加密套件 + * + * @param supportedCipherSuites 支持的加密套件 + * @return this + */ + public TlsSocketStrategyBuilder setSupportedCipherSuites(final String[] supportedCipherSuites) { + this.supportedCipherSuites = supportedCipherSuites; + return this; + } + + /** + * 设置SSL缓冲模式 + * + * @param sslBufferMode SSL缓冲模式 + * @return this + */ + public TlsSocketStrategyBuilder setSslBufferMode(final SSLBufferMode sslBufferMode) { + this.sslBufferMode = sslBufferMode; + return this; + } + + /** + * 设置主机名验证策略 + * + * @param hostnameVerificationPolicy 主机名验证策略 + * @return this + */ + public TlsSocketStrategyBuilder setHostnameVerificationPolicy(final HostnameVerificationPolicy hostnameVerificationPolicy) { + this.hostnameVerificationPolicy = hostnameVerificationPolicy; + return this; + } + + /** + * 设置主机名验证器 + * + * @param hostnameVerifier 主机名验证器 + * @return this + */ + public TlsSocketStrategyBuilder setHostnameVerifier(final HostnameVerifier hostnameVerifier) { + this.hostnameVerifier = hostnameVerifier; + return this; + } + + @Override + public TlsSocketStrategy build() { + return new DefaultClientTlsStrategy( + ObjUtil.defaultIfNull(sslContext, SSLContexts::createDefault), + supportedProtocols, + supportedCipherSuites, + ObjUtil.defaultIfNull(sslBufferMode, SSLBufferMode.STATIC), + ObjUtil.defaultIfNull(hostnameVerificationPolicy, HostnameVerificationPolicy.BOTH), + ObjUtil.defaultIfNull(hostnameVerifier, HttpsSupport::getDefaultHostnameVerifier) + ); + } +} diff --git a/hutool-log/src/main/java/org/dromara/hutool/log/engine/commons/ApacheCommonsLogEngine.java b/hutool-log/src/main/java/org/dromara/hutool/log/engine/commons/ApacheCommonsLogEngine.java index fc0a19d33..6ecf3a126 100644 --- a/hutool-log/src/main/java/org/dromara/hutool/log/engine/commons/ApacheCommonsLogEngine.java +++ b/hutool-log/src/main/java/org/dromara/hutool/log/engine/commons/ApacheCommonsLogEngine.java @@ -30,7 +30,7 @@ public class ApacheCommonsLogEngine extends AbsLogEngine { * 构造 */ public ApacheCommonsLogEngine() { - super("Apache Common Logging"); + super("Apache Commons Logging"); checkLogExist(org.apache.commons.logging.LogFactory.class); } diff --git a/hutool-log/src/main/java/org/dromara/hutool/log/engine/log4j/Log4jLog.java b/hutool-log/src/main/java/org/dromara/hutool/log/engine/log4j/Log4jLog.java index 4b00fbaa6..4b7e1b0cc 100644 --- a/hutool-log/src/main/java/org/dromara/hutool/log/engine/log4j/Log4jLog.java +++ b/hutool-log/src/main/java/org/dromara/hutool/log/engine/log4j/Log4jLog.java @@ -34,18 +34,33 @@ public class Log4jLog extends AbstractLog { private final Logger logger; // ------------------------------------------------------------------------- Constructor - public Log4jLog(final Logger logger) { - this.logger = logger; - } - + /** + * 构造 + * + * @param clazz 日志标识 + */ public Log4jLog(final Class clazz) { this((null == clazz) ? StrUtil.NULL : clazz.getName()); } + /** + * 构造 + * + * @param name 日志标识 + */ public Log4jLog(final String name) { this(Logger.getLogger(name)); } + /** + * 构造 + * + * @param logger 日志实现 + */ + public Log4jLog(final Logger logger) { + this.logger = logger; + } + @Override public String getName() { return logger.getName(); diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/csv/CsvBaseReader.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/csv/CsvBaseReader.java index cb8f844cb..f59287d9a 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/csv/CsvBaseReader.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/csv/CsvBaseReader.java @@ -16,11 +16,11 @@ package org.dromara.hutool.poi.csv; -import org.dromara.hutool.core.io.file.FileUtil; +import org.dromara.hutool.core.func.SerConsumer; import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IoUtil; +import org.dromara.hutool.core.io.file.PathUtil; import org.dromara.hutool.core.lang.Assert; -import org.dromara.hutool.core.func.SerConsumer; import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.ObjUtil; @@ -180,7 +180,7 @@ public class CsvBaseReader implements Serializable { */ public CsvData read(final Path path, final Charset charset) throws IORuntimeException { Assert.notNull(path, "path must not be null"); - return read(FileUtil.getReader(path, charset), true); + return read(PathUtil.getReader(path, charset), true); } /** diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/csv/CsvReader.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/csv/CsvReader.java index 54e5d82cd..00566789e 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/csv/CsvReader.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/csv/CsvReader.java @@ -20,6 +20,7 @@ import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.file.FileUtil; import org.dromara.hutool.core.func.SerConsumer; +import org.dromara.hutool.core.io.file.PathUtil; import java.io.Closeable; import java.io.File; @@ -102,7 +103,7 @@ public class CsvReader extends CsvBaseReader implements Iterable, Closea * @since 5.0.4 */ public CsvReader(final Path path, final Charset charset, final CsvReadConfig config) { - this(FileUtil.getReader(path, charset), config); + this(PathUtil.getReader(path, charset), config); } /**