maven依赖:
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
application.yml
sftp:
protocol: sftp
host:
port: 22
username: root
password:
spring:
servlet:
multipart:
max-file-size: 500MB
max-request-size: 500MB
注:springboot自带的tomcat会限制上传文件的大小,需要在yml文件里手动设置max-file-size
SftpProperties.java
@Data
@Component
@ConfigurationProperties(prefix = "sftp")
public class SftpProperties {
private String host;
private int port;
private String username;
private String password;
private String protocol;
}
SftpUtils.java
@Slf4j
@Component
public class SftpUtils {
@Resource
private SftpProperties sftpProperties;
public ChannelSftp createSftp() throws JSchException {
JSch jsch = new JSch();
log.info("Try to connect sftp[" + sftpProperties.getUsername() + "@" + sftpProperties.getHost() + "]");
Session session = createSession(jsch, sftpProperties.getHost(), sftpProperties.getUsername(), sftpProperties.getPort());
session.setPassword(sftpProperties.getPassword());
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
log.info("Session connected to {}.", sftpProperties.getHost());
Channel channel = session.openChannel(sftpProperties.getProtocol());
channel.connect();
log.info("Channel created to {}.", sftpProperties.getHost());
return (ChannelSftp) channel;
}
public Session createSession(JSch jsch, String host, String username, Integer port) throws JSchException {
Session session = null;
if (port <= 0) {
session = jsch.getSession(username, host);
} else {
session = jsch.getSession(username, host, port);
}
if (session == null) {
throw new RuntimeException(host + "session is null");
}
return session;
}
public void disconnect(ChannelSftp sftp) {
try {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
} else if (sftp.isClosed()) {
log.error("sftp 连接已关闭");
}
if (sftp.getSession() != null) {
sftp.getSession().disconnect();
}
}
} catch (JSchException e) {
log.error("sftp 断开连接失败,原因:{}", e.getMessage(), e);
}
}
}
SftpController.java
@RestController
public class SftpController {
@Autowired
private SftpService sftpService;
@PostMapping("/upload")
public void upload(String remotePath, MultipartFile file) {
sftpService.upload(remotePath, file);
}
@GetMapping("/download")
public void download(String remotePath, String localPath) {
sftpService.download(remotePath, localPath);
}
}
SftpServiceImpl.java
@Service
@Slf4j
public class SftpServiceImpl implements SftpService {
@Autowired
private SftpUtils sftpUtils;
@Override
public void upload(String remotePath, MultipartFile file) {
ChannelSftp sftp = null;
try {
// 开启sftp连接
sftp = sftpUtils.createSftp();
sftp.cd(remotePath);
log.info("修改目录为:{}", remotePath);
// 上传文件
sftp.put(file.getInputStream(), file.getOriginalFilename());
log.info("上传文件成功,目标目录:{}", remotePath);
} catch (Exception e) {
log.error("上传文件失败,原因:{}", e.getMessage(), e);
throw new RuntimeException("上传文件失败");
} finally {
// 关闭sftp
sftpUtils.disconnect(sftp);
}
}
@Override
public void download(String remotePath, String localPath) {
ChannelSftp sftp = null;
OutputStream outputStream = null;
try {
sftp = sftpUtils.createSftp();
String path = remotePath.substring(0, remotePath.lastIndexOf("/"));
String fileName = remotePath.substring(remotePath.lastIndexOf("/") + 1);
System.out.println("path:" + path);
System.out.println("fileName:" + fileName);
sftp.cd(path);
if(isFileExist(remotePath, sftp)) { //如果远程文件存在
File localFile = new File(localPath);
if(!localFile.exists()) { //如果本地目录不存在,则创建目录
localFile.mkdirs();
}
outputStream = new FileOutputStream(new File(localPath + "/" + fileName));
sftp.get(fileName, outputStream);
log.info("下载文件成功");
} else {
log.error("远程文件不存在");
throw new RuntimeException("远程文件不存在");
}
} catch (Exception e) {
log.error("sftp文件下载失败,目标文件名:{},原因:{}", remotePath, e.getMessage(), e);
throw new RuntimeException("远程文件下载失败");
} finally {
// 关闭sftp
sftpUtils.disconnect(sftp);
}
}
//判断文件是否存在
private boolean isFileExist(String remotePath, ChannelSftp sftp) {
try {
SftpATTRS lstat = sftp.lstat(remotePath);
return lstat != null;
} catch (Exception e) {
log.error("判断文件是否存在失败,原因:{}", e.getMessage(), e);
return false;
}
}
}
接口测试:
上传接口:
下载接口: