Commit 568216084e83e0dcb6f299c42f6977953035afa0

Authored by YunaiV
1 parent 6d1b7ec4

feat:【infra 基础设施】ftp、sftp 库升级与兼容

yudao-dependencies/pom.xml
... ... @@ -61,7 +61,7 @@
61 61 <transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
62 62 <commons-net.version>3.11.1</commons-net.version>
63 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 65 <tika-core.version>3.2.2</tika-core.version>
66 66 <ip2region.version>2.7.0</ip2region.version>
67 67 <bizlog-sdk.version>3.0.6</bizlog-sdk.version>
... ... @@ -526,7 +526,7 @@
526 526 <version>${commons-net.version}</version>
527 527 </dependency>
528 528 <dependency>
529   - <groupId>com.jcraft</groupId>
  529 + <groupId>com.github.mwiede</groupId>
530 530 <artifactId>jsch</artifactId> <!-- 解决 sftp 连接 -->
531 531 <version>${jsch.version}</version>
532 532 </dependency>
... ...
yudao-module-infra/pom.xml
... ... @@ -101,7 +101,7 @@
101 101 <artifactId>commons-net</artifactId> <!-- 文件客户端:解决 ftp 连接 -->
102 102 </dependency>
103 103 <dependency>
104   - <groupId>com.jcraft</groupId>
  104 + <groupId>com.github.mwiede</groupId>
105 105 <artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 -->
106 106 </dependency>
107 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 4 import cn.hutool.core.util.CharsetUtil;
5 5 import cn.hutool.core.util.StrUtil;
6 6 import cn.hutool.extra.ftp.Ftp;
  7 +import cn.hutool.extra.ftp.FtpConfig;
7 8 import cn.hutool.extra.ftp.FtpException;
8 9 import cn.hutool.extra.ftp.FtpMode;
9 10 import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
... ... @@ -18,6 +19,15 @@ import java.io.ByteArrayOutputStream;
18 19 */
19 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 31 private Ftp ftp;
22 32  
23 33 public FtpFileClient(Long id, FtpFileClientConfig config) {
... ... @@ -26,9 +36,12 @@ public class FtpFileClient extends AbstractFileClient&lt;FtpFileClientConfig&gt; {
26 36  
27 37 @Override
28 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 47 @Override
... ... @@ -72,4 +85,4 @@ public class FtpFileClient extends AbstractFileClient&lt;FtpFileClientConfig&gt; {
72 85 ftp.reconnectIfTimeout();
73 86 }
74 87  
75   -}
76 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 1 package cn.iocoder.yudao.module.infra.framework.file.core.client.ftp;
2 2  
3 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 4 import jakarta.validation.constraints.NotEmpty;
8 5 import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +import org.hibernate.validator.constraints.URL;
9 8  
10 9 /**
11 10 * Ftp 文件客户端的配置类
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/sftp/SftpFileClient.java
1 1 package cn.iocoder.yudao.module.infra.framework.file.core.client.sftp;
2 2  
3 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 8 import cn.hutool.extra.ssh.Sftp;
5 9 import cn.iocoder.yudao.framework.common.util.io.FileUtils;
6 10 import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
  11 +import com.jcraft.jsch.JSch;
7 12  
8 13 import java.io.File;
9 14  
... ... @@ -14,6 +19,20 @@ import java.io.File;
14 19 */
15 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 36 private Sftp sftp;
18 37  
19 38 public SftpFileClient(Long id, SftpFileClientConfig config) {
... ... @@ -22,18 +41,27 @@ public class SftpFileClient extends AbstractFileClient&lt;SftpFileClientConfig&gt; {
22 41  
23 42 @Override
24 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 52 @Override
30 53 public String upload(byte[] content, String path, String type) {
31 54 // 执行写入
32 55 String filePath = getFilePath(path);
  56 + String fileName = FileUtil.getName(filePath);
  57 + String dir = StrUtil.removeSuffix(filePath, fileName);
33 58 File file = FileUtils.createTempFile(content);
34 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 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 1 package cn.iocoder.yudao.module.infra.framework.file.core.client.sftp;
2 2  
3 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 4 import jakarta.validation.constraints.NotEmpty;
8 5 import jakarta.validation.constraints.NotNull;
  6 +import lombok.Data;
  7 +import org.hibernate.validator.constraints.URL;
9 8  
10 9 /**
11 10 * Sftp 文件客户端的配置类
... ...