Commit 568216084e83e0dcb6f299c42f6977953035afa0

Authored by YunaiV
1 parent 6d1b7ec4

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

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&lt;FtpFileClientConfig&gt; { @@ -26,9 +36,12 @@ public class FtpFileClient extends AbstractFileClient&lt;FtpFileClientConfig&gt; {
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&lt;FtpFileClientConfig&gt; { @@ -72,4 +85,4 @@ public class FtpFileClient extends AbstractFileClient&lt;FtpFileClientConfig&gt; {
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&lt;SftpFileClientConfig&gt; { @@ -22,18 +41,27 @@ public class SftpFileClient extends AbstractFileClient&lt;SftpFileClientConfig&gt; {
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 文件客户端的配置类