# haibaracp-spring-boot-starter
**Repository Path**: hligy/haibaracp-spring-boot-starter
## Basic Information
- **Project Name**: haibaracp-spring-boot-starter
- **Description**: SFTP文件传输的Spring Boot Starter,通过与Spring Data XxxTemplate模板类一样的 SftpTemplate 轻松完成文件传输。使用Commons-pool2作为连接池。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: 2.x
- **Homepage**: https://github.com/hligaty/haibaracp-spring-boot-starter
- **GVP Project**: No
## Statistics
- **Stars**: 14
- **Forks**: 4
- **Created**: 2021-11-28
- **Last Updated**: 2025-08-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: SpringBoot, SFTP
## README
[English](README.md) | [中文](README_zh_CN.md)
# HaibaraCP
> **Github:[hligaty/haibaracp-spring-boot-starter: SFTP Connect Pool (github.com)](https://github.com/hligaty/haibaracp-spring-boot-starter)**
> **Gitee:[haibaracp-spring-boot-starter: SFTP Connect Pool (gitee.com)](https://gitee.com/hligy/haibaracp-spring-boot-starter)**
> **欢迎使用和Star支持,如使用过程中碰到问题,可以提出Issue,我会尽力完善**
## 介绍
HaibaraCP 是一个 SFTP 的 SpringBoot Starter,支持密码和密钥登录以及多个 Host 连接,并提供和 RedisTemplate 一样优雅的 SftpTemplate。SFTP 通过 SSH 建立连接,而 SSH 连接数默认是有限的,10 个以外的连接将有 30 % 的概率连接失败,当超过 100 个连接时将拒绝创建新连接,因此要避免频繁创建新连接。
## Maven 依赖
| spring boot version | haibaracp |
| :-----------------: |:---------:|
| 2.x.x | 1.3.2 |
| 3.x.x | 2.1.2 |
依赖 Apache commons-pool2:
```xml
io.github.hligaty
haibaracp-spring-boot-starter
x.x.x
org.apache.commons
commons-pool2
```
## 配置
详细的配置属性说明见开发工具的自动提示。
### 密码登录
```yml
sftp:
enabled-log: false
host: localhost
port: 22
username: root
password: 123456
kex: diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256
```
### 密钥登录
```yml
sftp:
enabled-log: false
host: localhost
port: 22
username: root
strict-host-key-checking: true
key-path: C:\\Users\\user\\.ssh\\id_rsa
password: Jui8cv@kK9!0
kex: diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256
```
### 连接池(可以不配置)
```yml
sftp:
pool:
min-idle: 1
max-idle: 8
max-active: 8
max-wait: -1
test-on-borrow: true
test-on-return: false
test-while-idle: true
time-between-eviction-runs: 600000
min-evictable-idle-time-millis: 1800000
```
## 用法
HaibaraCP 提供 SftpTemplate 类,它与 `spring-boot-starter-data-redis` 提供的 RedisTemplate 使用方法相同,任意方式注入即可使用:
```java
@Component
public class XXXService {
private final SftpTemplate sftpTemplate;
public XXXService(SftpTemplate sftpTemplate) {
this.sftpTemplate = sftpTemplate;
}
public void service(String from, OutputStream to) throws Exception {
sftpTemplate.download(from, to);
}
}
```
## API
- sftp 操作可能会改变工作目录,因此在连接返回给池前,框架会重置工作目录为原始目录。注意这只会重置远端工作路径,不会重置本地工作路径(通常你并不关心本地工作路径)。
下面的介绍全部使用 `配置` 章节中的配置进行说明,因此初始工作目录是 `/root`。
### upload
上传文件,该方法会递归创建上传的远程文件所在的父目录。
```java
// 上传 D:\\aptx4869.docx 到 /home/haibara/aptx4869.docx
sftpTemplate.upload("D:\\aptx4869.docx", "/home/haibara/aptx4869.docx");
// 上传 D:\\aptx4869.pdf 到 /root/haibara/aptx4869.pdf
sftpTemplate.upload("D:\\aptx4869.pdf", "haibara/aptx4869.pdf");
// 上传 D:\\aptx4869.doc 到 /root/aptx4869.doc
sftpTemplate.upload("D:\\aptx4869.doc", "aptx4869.doc");
```
### download
下载文件,该方法只会创建下载的本地文件,不会创建本地文件的父目录。
```java
// 下载 /home/haibara/aptx4869.docx 到 D:\\aptx4869.docx
sftpTemplate.download("/home/haibara/aptx4869.docx", "D:\\aptx4869.docx");
// 下载 /root/haibara/aptx4869.pdf 到 D:\\aptx4869.pdf
sftpTemplate.download("haibara/aptx4869.pdf", "D:\\aptx4869.pdf");
// 下载 /root/aptx4869.doc 到 D:\\aptx4869.doc
sftpTemplate.download("aptx4869.doc", "D:\\aptx4869.doc");
```
### exists
```java
// 测试 /home/haibara/aptx4869.docx 是否存在
boolean result1 = sftpTemplate.exists("/home/haibara/aptx4869.pdf");
// 测试 /root/haibara/aptx4869.docx 是否存在
boolean result2 = sftpTemplate.exists("haibara/aptx4869.docx");
// 测试 /root/aptx4869.docx 是否存在
boolean result3 = sftpTemplate.exists("aptx4869.doc");
```
### list
```java
// 查看文件 /home/haibara/aptx4869.pdf
LsEntry[] list1 = sftpTemplate.list("/home/haibara/aptx4869.pdf");
// 查看文件 /root/haibara/aptx4869.docx
LsEntry[] list2 = sftpTemplate.list("haibara/aptx4869.docx");
// 查看文件 /root/aptx4869.doc
LsEntry[] list3 = sftpTemplate.list("aptx4869.doc");
// 查看目录 /home/haibara
LsEntry[] list4 = sftpTemplate.list("/home/haibara");
// 查看目录 /root/haibara
LsEntry[] list5 = sftpTemplate.list("haibara");
```
### execute
`execute(SftpCallback action)` 用于执行自定义 SFTP 操作,比如查看 SFTP 默认目录(关于 ChannelSftp 的其他用法请参考 jsch 的 API):
```java
String dir = sftpTemplate.execute(ChannelSftp::pwd);
```
Jsch 的 ChannelSftp 提供了很多基础的方法,对于 execute 来说有点不太便捷,你可以使用 ChannelSftpWrapper 类来更便捷的使用 ChannelSftp,SftpTemplate 所有的方法也都是通过它来实现的。
### executeWithoutResult
`executeWithoutResult(SftpCallbackWithoutResult action)`用于执行自定义没有返回值的SFTP操作,比如下载文件(ChannelSftp的其他用途,请参考 jsch 的 API):
```java
try (OutputStream outputStream = Files.newOutputStream(Paths.get("/root/aptx4869.doc"))) {
sftpTemplate.executeWithoutResult(channelSftp -> channelSftp.get("aptx4869.doc", outputStream));
}
```
## SftpSessionFactory
用于创建 SftpSession 的工厂,在需要自定义创建 Jsch Session 或扩展 SftpSession功能时你会使用到它,比如:
```java
@Configuration(proxyBeanMethods = false)
public class SftpConfiguration {
@Bean
public SftpSessionFactory sftpSessionFactory(ClientProperties clientProperties, PoolProperties poolProperties) {
return new SftpSessionFactory(clientProperties, poolProperties) {
@Override
public SftpSession getSftpSession(ClientProperties clientProperties) {
return new XxSftpSession(clientProperties);
}
};
}
public static class XxSftpSession extends SftpSession {
private Channel fooChannel;
public FooSftpSession(ClientProperties clientProperties) {
super(clientProperties);
}
@Override
protected Session createJschSession(ClientProperties clientProperties) throws Exception {
Session jschSession = super.createJschSession(clientProperties);
fooChannel = jschSession.openChannel("foo");
return jschSession;
}
public Channel getFooChannel() {
return xxChannel;
}
}
@Bean
public SftpTemplate sftpTemplate(SftpSessionFactory sftpSessionFactory) {
return new SftpTemplate<>(sftpSessionFactory);
}
}
```
然后在 SftpTemplate 中这样使用它:
```java
sftpTemplate.executeSessionWithoutResult(sftpSession -> {
Channel fooChannel = sftpSession.getFooChannel();
});
```
## 密钥格式
OpenSSH 自 7.8 起,默认的密钥格式由
```
-----BEGIN RSA PRIVATE KEY-----
xxx
-----END RSA PRIVATE KEY-----
```
变更为:
```
-----BEGIN OPENSSH PRIVATE KEY-----
xxx
-----END OPENSSH PRIVATE KEY-----
```
Haibaracp 使用 Jsch 作为 SFTP 的实现,而 Jsch 不支持新的格式,因此你需要一些小改动:
1. 如果密钥由你生成,仅需在 `ssh-keygen` 命令后加上 `-m PEM` 以生成旧版的密钥继续使用。
2. 如果你无法自己获取旧版密钥,此时必须更改 POM,将 Jcraft 的 Jsch 更改为其他人 fork 的 Jsch 库(Jcraft 自 2018 年推送的 0.1.55 版本后没有任何的消息),比如:
```xml
io.github.hligaty
haibaracp-spring-boot-starter
x.x.x
com.jcraft
jsch
com.github.mwiede
jsch
0.1.72
```
否则你将看到 [JSchException: invalid privatekey](https://github.com/mwiede/jsch/issues/12#issuecomment-662863338)。
## 变更记录
[CHANGELOG.md](CHANGELOG.md)
## Thanks for free JetBrains Open Source license
