Commit 568216084e83e0dcb6f299c42f6977953035afa0
1 parent
6d1b7ec4
feat:【infra 基础设施】ftp、sftp 库升级与兼容
Showing
6 changed files
with
56 additions
and
17 deletions
yudao-dependencies/pom.xml
| @@ -61,7 +61,7 @@ | @@ -61,7 +61,7 @@ | ||
| 61 | <transmittable-thread-local.version>2.14.5</transmittable-thread-local.version> | 61 | <transmittable-thread-local.version>2.14.5</transmittable-thread-local.version> |
| 62 | <commons-net.version>3.11.1</commons-net.version> | 62 | <commons-net.version>3.11.1</commons-net.version> |
| 63 | <commons-lang3.version>3.18.0</commons-lang3.version> | 63 | <commons-lang3.version>3.18.0</commons-lang3.version> |
| 64 | - <jsch.version>0.1.55</jsch.version> | 64 | + <jsch.version>2.27.3</jsch.version> |
| 65 | <tika-core.version>3.2.2</tika-core.version> | 65 | <tika-core.version>3.2.2</tika-core.version> |
| 66 | <ip2region.version>2.7.0</ip2region.version> | 66 | <ip2region.version>2.7.0</ip2region.version> |
| 67 | <bizlog-sdk.version>3.0.6</bizlog-sdk.version> | 67 | <bizlog-sdk.version>3.0.6</bizlog-sdk.version> |
| @@ -526,7 +526,7 @@ | @@ -526,7 +526,7 @@ | ||
| 526 | <version>${commons-net.version}</version> | 526 | <version>${commons-net.version}</version> |
| 527 | </dependency> | 527 | </dependency> |
| 528 | <dependency> | 528 | <dependency> |
| 529 | - <groupId>com.jcraft</groupId> | 529 | + <groupId>com.github.mwiede</groupId> |
| 530 | <artifactId>jsch</artifactId> <!-- 解决 sftp 连接 --> | 530 | <artifactId>jsch</artifactId> <!-- 解决 sftp 连接 --> |
| 531 | <version>${jsch.version}</version> | 531 | <version>${jsch.version}</version> |
| 532 | </dependency> | 532 | </dependency> |
yudao-module-infra/pom.xml
| @@ -101,7 +101,7 @@ | @@ -101,7 +101,7 @@ | ||
| 101 | <artifactId>commons-net</artifactId> <!-- 文件客户端:解决 ftp 连接 --> | 101 | <artifactId>commons-net</artifactId> <!-- 文件客户端:解决 ftp 连接 --> |
| 102 | </dependency> | 102 | </dependency> |
| 103 | <dependency> | 103 | <dependency> |
| 104 | - <groupId>com.jcraft</groupId> | 104 | + <groupId>com.github.mwiede</groupId> |
| 105 | <artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 --> | 105 | <artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 --> |
| 106 | </dependency> | 106 | </dependency> |
| 107 | <!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 --> | 107 | <!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 --> |
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/ftp/FtpFileClient.java
| @@ -4,6 +4,7 @@ import cn.hutool.core.io.FileUtil; | @@ -4,6 +4,7 @@ import cn.hutool.core.io.FileUtil; | ||
| 4 | import cn.hutool.core.util.CharsetUtil; | 4 | import cn.hutool.core.util.CharsetUtil; |
| 5 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.hutool.extra.ftp.Ftp; | 6 | import cn.hutool.extra.ftp.Ftp; |
| 7 | +import cn.hutool.extra.ftp.FtpConfig; | ||
| 7 | import cn.hutool.extra.ftp.FtpException; | 8 | import cn.hutool.extra.ftp.FtpException; |
| 8 | import cn.hutool.extra.ftp.FtpMode; | 9 | import cn.hutool.extra.ftp.FtpMode; |
| 9 | import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient; | 10 | import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient; |
| @@ -18,6 +19,15 @@ import java.io.ByteArrayOutputStream; | @@ -18,6 +19,15 @@ import java.io.ByteArrayOutputStream; | ||
| 18 | */ | 19 | */ |
| 19 | public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> { | 20 | public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> { |
| 20 | 21 | ||
| 22 | + /** | ||
| 23 | + * 连接超时时间,单位:毫秒 | ||
| 24 | + */ | ||
| 25 | + private static final Long CONNECTION_TIMEOUT = 3000L; | ||
| 26 | + /** | ||
| 27 | + * 读写超时时间,单位:毫秒 | ||
| 28 | + */ | ||
| 29 | + private static final Long SO_TIMEOUT = 10000L; | ||
| 30 | + | ||
| 21 | private Ftp ftp; | 31 | private Ftp ftp; |
| 22 | 32 | ||
| 23 | public FtpFileClient(Long id, FtpFileClientConfig config) { | 33 | public FtpFileClient(Long id, FtpFileClientConfig config) { |
| @@ -26,9 +36,12 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> { | @@ -26,9 +36,12 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> { | ||
| 26 | 36 | ||
| 27 | @Override | 37 | @Override |
| 28 | protected void doInit() { | 38 | protected void doInit() { |
| 29 | - // 初始化 Ftp 对象 | ||
| 30 | - this.ftp = new Ftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword(), | ||
| 31 | - CharsetUtil.CHARSET_UTF_8, null, null, FtpMode.valueOf(config.getMode())); | 39 | + // 初始化 Ftp 对象:https://gitee.com/zhijiantianya/yudao-cloud/pulls/207/ |
| 40 | + FtpConfig ftpConfig = new FtpConfig(config.getHost(), config.getPort(), config.getUsername(), config.getPassword(), | ||
| 41 | + CharsetUtil.CHARSET_UTF_8, null, null); | ||
| 42 | + ftpConfig.setConnectionTimeout(CONNECTION_TIMEOUT); | ||
| 43 | + ftpConfig.setSoTimeout(SO_TIMEOUT); | ||
| 44 | + this.ftp = new Ftp(ftpConfig, FtpMode.valueOf(config.getMode())); | ||
| 32 | } | 45 | } |
| 33 | 46 | ||
| 34 | @Override | 47 | @Override |
| @@ -72,4 +85,4 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> { | @@ -72,4 +85,4 @@ public class FtpFileClient extends AbstractFileClient<FtpFileClientConfig> { | ||
| 72 | ftp.reconnectIfTimeout(); | 85 | ftp.reconnectIfTimeout(); |
| 73 | } | 86 | } |
| 74 | 87 | ||
| 75 | -} | ||
| 76 | \ No newline at end of file | 88 | \ No newline at end of file |
| 89 | +} |
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/ftp/FtpFileClientConfig.java
| 1 | package cn.iocoder.yudao.module.infra.framework.file.core.client.ftp; | 1 | package cn.iocoder.yudao.module.infra.framework.file.core.client.ftp; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig; | 3 | import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig; |
| 4 | -import lombok.Data; | ||
| 5 | -import org.hibernate.validator.constraints.URL; | ||
| 6 | - | ||
| 7 | import jakarta.validation.constraints.NotEmpty; | 4 | import jakarta.validation.constraints.NotEmpty; |
| 8 | import jakarta.validation.constraints.NotNull; | 5 | import jakarta.validation.constraints.NotNull; |
| 6 | +import lombok.Data; | ||
| 7 | +import org.hibernate.validator.constraints.URL; | ||
| 9 | 8 | ||
| 10 | /** | 9 | /** |
| 11 | * Ftp 文件客户端的配置类 | 10 | * Ftp 文件客户端的配置类 |
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/sftp/SftpFileClient.java
| 1 | package cn.iocoder.yudao.module.infra.framework.file.core.client.sftp; | 1 | package cn.iocoder.yudao.module.infra.framework.file.core.client.sftp; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.io.FileUtil; | 3 | import cn.hutool.core.io.FileUtil; |
| 4 | +import cn.hutool.core.util.CharsetUtil; | ||
| 5 | +import cn.hutool.core.util.StrUtil; | ||
| 6 | +import cn.hutool.extra.ftp.FtpConfig; | ||
| 7 | +import cn.hutool.extra.ssh.JschRuntimeException; | ||
| 4 | import cn.hutool.extra.ssh.Sftp; | 8 | import cn.hutool.extra.ssh.Sftp; |
| 5 | import cn.iocoder.yudao.framework.common.util.io.FileUtils; | 9 | import cn.iocoder.yudao.framework.common.util.io.FileUtils; |
| 6 | import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient; | 10 | import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient; |
| 11 | +import com.jcraft.jsch.JSch; | ||
| 7 | 12 | ||
| 8 | import java.io.File; | 13 | import java.io.File; |
| 9 | 14 | ||
| @@ -14,6 +19,20 @@ import java.io.File; | @@ -14,6 +19,20 @@ import java.io.File; | ||
| 14 | */ | 19 | */ |
| 15 | public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> { | 20 | public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> { |
| 16 | 21 | ||
| 22 | + /** | ||
| 23 | + * 连接超时时间,单位:毫秒 | ||
| 24 | + */ | ||
| 25 | + private static final Long CONNECTION_TIMEOUT = 3000L; | ||
| 26 | + /** | ||
| 27 | + * 读写超时时间,单位:毫秒 | ||
| 28 | + */ | ||
| 29 | + private static final Long SO_TIMEOUT = 10000L; | ||
| 30 | + | ||
| 31 | + static { | ||
| 32 | + // 某些旧的 sftp 服务器仅支持 ssh-dss 协议,该协议并不安全,默认不支持该协议,按需添加 | ||
| 33 | + JSch.setConfig("server_host_key", JSch.getConfig("server_host_key") + ",ssh-dss"); | ||
| 34 | + } | ||
| 35 | + | ||
| 17 | private Sftp sftp; | 36 | private Sftp sftp; |
| 18 | 37 | ||
| 19 | public SftpFileClient(Long id, SftpFileClientConfig config) { | 38 | public SftpFileClient(Long id, SftpFileClientConfig config) { |
| @@ -22,18 +41,27 @@ public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> { | @@ -22,18 +41,27 @@ public class SftpFileClient extends AbstractFileClient<SftpFileClientConfig> { | ||
| 22 | 41 | ||
| 23 | @Override | 42 | @Override |
| 24 | protected void doInit() { | 43 | protected void doInit() { |
| 25 | - // 初始化 Ftp 对象 | ||
| 26 | - this.sftp = new Sftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword()); | 44 | + // 初始化 Sftp 对象 |
| 45 | + FtpConfig ftpConfig = new FtpConfig(config.getHost(), config.getPort(), config.getUsername(), config.getPassword(), | ||
| 46 | + CharsetUtil.CHARSET_UTF_8, null, null); | ||
| 47 | + ftpConfig.setConnectionTimeout(CONNECTION_TIMEOUT); | ||
| 48 | + ftpConfig.setSoTimeout(SO_TIMEOUT); | ||
| 49 | + this.sftp = new Sftp(ftpConfig); | ||
| 27 | } | 50 | } |
| 28 | 51 | ||
| 29 | @Override | 52 | @Override |
| 30 | public String upload(byte[] content, String path, String type) { | 53 | public String upload(byte[] content, String path, String type) { |
| 31 | // 执行写入 | 54 | // 执行写入 |
| 32 | String filePath = getFilePath(path); | 55 | String filePath = getFilePath(path); |
| 56 | + String fileName = FileUtil.getName(filePath); | ||
| 57 | + String dir = StrUtil.removeSuffix(filePath, fileName); | ||
| 33 | File file = FileUtils.createTempFile(content); | 58 | File file = FileUtils.createTempFile(content); |
| 34 | reconnectIfTimeout(); | 59 | reconnectIfTimeout(); |
| 35 | - sftp.mkDirs(FileUtil.getParent(filePath, 1)); // 需要创建父目录,不然会报错 | ||
| 36 | - sftp.upload(filePath, file); | 60 | + sftp.mkDirs(dir); // 需要创建父目录,不然会报错 |
| 61 | + boolean success = sftp.upload(filePath, file); | ||
| 62 | + if (!success) { | ||
| 63 | + throw new JschRuntimeException(StrUtil.format("上传文件到目标目录 ({}) 失败", filePath)); | ||
| 64 | + } | ||
| 37 | // 拼接返回路径 | 65 | // 拼接返回路径 |
| 38 | return super.formatFileUrl(config.getDomain(), path); | 66 | return super.formatFileUrl(config.getDomain(), path); |
| 39 | } | 67 | } |
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/sftp/SftpFileClientConfig.java
| 1 | package cn.iocoder.yudao.module.infra.framework.file.core.client.sftp; | 1 | package cn.iocoder.yudao.module.infra.framework.file.core.client.sftp; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig; | 3 | import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig; |
| 4 | -import lombok.Data; | ||
| 5 | -import org.hibernate.validator.constraints.URL; | ||
| 6 | - | ||
| 7 | import jakarta.validation.constraints.NotEmpty; | 4 | import jakarta.validation.constraints.NotEmpty; |
| 8 | import jakarta.validation.constraints.NotNull; | 5 | import jakarta.validation.constraints.NotNull; |
| 6 | +import lombok.Data; | ||
| 7 | +import org.hibernate.validator.constraints.URL; | ||
| 9 | 8 | ||
| 10 | /** | 9 | /** |
| 11 | * Sftp 文件客户端的配置类 | 10 | * Sftp 文件客户端的配置类 |