springboot SFTP 文件上传下载功能
2021-01-08 08:33
标签:false lombok @param getpass stat charset 提示 wan ann 新增sftp.properies 文件保存 sftp服务器信息 SftpProperties.java 文件 Application.java 文件启动类 引入属性加上文件上传大小的设置 文件上传下载的接口 FileSystemController.java 启动项目并用postman测试 选择文件后请求,响应true 查看控制台打印输出: 登陆文件服务器 查看相应目录下: 文件已经被上传 springboot SFTP 文件上传下载功能 标签:false lombok @param getpass stat charset 提示 wan ann 原文地址:https://www.cnblogs.com/wanjun-top/p/12967795.html# 协议
sftp.client.protocol=sftp
# ip地址
sftp.client.host=改成自己的文件服务器地址
# 端口
sftp.client.port=22
# 用户名
sftp.client.username=root
# 密码
sftp.client.password=改成自己的密码
# 文件上传根路径
sftp.client.root=/home/sftp/
# 密钥文件路径
sftp.client.privateKey=
# 密钥的密码
sftp.client.passphrase=
#
sftp.client.sessionStrictHostKeyChecking=no
# session连接超时时间
sftp.client.sessionConnectTimeout=15000
# channel连接超时时间
sftp.client.channelConnectedTimeout=15000
package cn.rc.properties;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
public class SftpProperties {
@Value("${sftp.client.host}")
private String host;
@Value("${sftp.client.port}")
private Integer port;
@Value("${sftp.client.protocol}")
private String protocol;
@Value("${sftp.client.username}")
private String username;
@Value("${sftp.client.password}")
private String password;
@Value("${sftp.client.root}")
private String root;
@Value("${sftp.client.privateKey}")
private String privateKey;
@Value("${sftp.client.passphrase}")
private String passphrase;
@Value("${sftp.client.sessionStrictHostKeyChecking}")
private String sessionStrictHostKeyChecking;
@Value("${sftp.client.sessionConnectTimeout}")
private Integer sessionConnectTimeout;
@Value("${sftp.client.channelConnectedTimeout}")
private Integer channelConnectedTimeout;
}
/**
* Eureka服务端
*
* @author wanjun
*/
@SpringBootApplication
@EnableDiscoveryClient
@Slf4j
@MapperScan(basePackages = {"cn.rc.mapper"})
@PropertySource({"sftp.properties"})
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
/**
* 文件上传配置
* @return
*/
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//文件最大
//factory.setMaxFileSize("1024KB"); //KB,MB
/// 设置总上传数据总大小
factory.setMaxRequestSize("20480KB"); //最大上传为4M
return factory.createMultipartConfig();
}
}
package cn.rc.controller;
import cn.rc.properties.SftpProperties;
import cn.rc.service.FileSystemService;
import com.oracle.tools.packager.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
@Controller
public class FileSystemController {
@Autowired
private FileSystemService fileSystemService;
/**
* 实现多文件上传
*/
@RequestMapping(value = "upload", method = RequestMethod.POST)
@ResponseBody
public Boolean upload(@RequestParam("files") List
FileSystemServicepackage cn.rc.service;
import java.io.File;
import java.io.InputStream;
public interface FileSystemService {
boolean uploadFile(String targetPath, InputStream inputStream) throws Exception;
boolean uploadFile(String targetPath, File file) throws Exception;
File downloadFile(String targetPath) throws Exception;
boolean deleteFile(String targetPath) throws Exception;
}
FileSystemServiceImpl.javapackage cn.rc.service.impl;
import cn.rc.properties.SftpProperties;
import cn.rc.service.FileSystemService;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.Arrays;
@Slf4j
@Service("fileSystemService")
public class FileSystemServiceImpl implements FileSystemService {
@Autowired
private SftpProperties config;
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
private static final String SESSION_CONFIG_STRICT_HOST_KEY_CHECKING = "StrictHostKeyChecking";
/**
* 创建SFTP连接
*
* @return
* @throws Exception
*/
private ChannelSftp createSftp() throws Exception {
JSch jsch = new JSch();
log.info("Try to connect sftp[" + config.getUsername() + "@" + config.getHost() + "], use password[" + config.getPassword() + "]");
Session session = createSession(jsch, config.getHost(), config.getUsername(), config.getPort());
session.setPassword(config.getPassword());
session.connect(config.getSessionConnectTimeout());
log.info("Session connected to {}.", config.getHost());
Channel channel = session.openChannel(config.getProtocol());
channel.connect(config.getChannelConnectedTimeout());
log.info("Channel created to {}.", config.getHost());
return (ChannelSftp) channel;
}
/**
* 加密秘钥方式登陆
*
* @return
*/
private ChannelSftp connectByKey() throws Exception {
JSch jsch = new JSch();
// 设置密钥和密码 ,支持密钥的方式登陆
if (StringUtils.isNotBlank(config.getPrivateKey())) {
if (StringUtils.isNotBlank(config.getPassphrase())) {
// 设置带口令的密钥
jsch.addIdentity(config.getPrivateKey(), config.getPassphrase());
} else {
// 设置不带口令的密钥
jsch.addIdentity(config.getPrivateKey());
}
}
log.info("Try to connect sftp[" + config.getUsername() + "@" + config.getHost() + "], use private key[" + config.getPrivateKey()
+ "] with passphrase[" + config.getPassphrase() + "]");
Session session = createSession(jsch, config.getHost(), config.getUsername(), config.getPort());
// 设置登陆超时时间
session.connect(config.getSessionConnectTimeout());
log.info("Session connected to " + config.getHost() + ".");
// 创建sftp通信通道
Channel channel = session.openChannel(config.getProtocol());
channel.connect(config.getChannelConnectedTimeout());
log.info("Channel created to " + config.getHost() + ".");
return (ChannelSftp) channel;
}
/**
* 创建session
*
* @param jsch
* @param host
* @param username
* @param port
* @return
* @throws Exception
*/
private Session createSession(JSch jsch, String host, String username, Integer port) throws Exception {
Session session = null;
if (port ) {
session = jsch.getSession(username, host);
} else {
session = jsch.getSession(username, host, port);
}
if (session == null) {
throw new Exception(host + " session is null");
}
session.setConfig(SESSION_CONFIG_STRICT_HOST_KEY_CHECKING, config.getSessionStrictHostKeyChecking());
return session;
}
/**
* 关闭连接
*
* @param sftp
*/
private void disconnect(ChannelSftp sftp) {
try {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
} else if (sftp.isClosed()) {
log.info("sftp is closed already");
}
if (null != sftp.getSession()) {
sftp.getSession().disconnect();
}
}
} catch (JSchException e) {
e.printStackTrace();
}
}
/**
* 将inputStream上传到指定路径下(单级或多级目录)
*
* @param targetPath 路径+文件名 比如/ home/513_education/test.xlsl
* @param inputStream
* @return
* @throws Exception
*/
@Override
public boolean uploadFile(String targetPath, InputStream inputStream) throws Exception {
ChannelSftp sftp = this.createSftp();
try {
sftp.cd(config.getRoot());
log.info("Change path to {}", config.getRoot());
int index = targetPath.lastIndexOf("/");
String fileDir = targetPath.substring(0, index);
String fileName = targetPath.substring(index + 1);
boolean dirs = this.createDirs(fileDir, sftp);
if (!dirs) {
log.error("Remote path error. path:{}", targetPath);
throw new Exception("Upload File failure");
}
sftp.put(inputStream, fileName);
return true;
} catch (Exception e) {
log.error("Upload file failure. TargetPath: {}", targetPath, e);
throw new Exception("Upload File failure");
} finally {
this.disconnect(sftp);
}
}
/**
* 创建多级目录
*
* @param dirPath
* @param sftp
* @return
*/
private boolean createDirs(String dirPath, ChannelSftp sftp) {
if (dirPath != null && !dirPath.isEmpty()
&& sftp != null) {
String[] dirs = Arrays.stream(dirPath.split("/"))
.filter(StringUtils::isNotBlank)
.toArray(String[]::new);
for (String dir : dirs) {
try {
sftp.cd(dir);
log.info("Change directory {}", dir);
} catch (Exception e) {
try {
sftp.mkdir(dir);
log.info("Create directory {}", dir);
} catch (SftpException e1) {
log.error("Create directory failure, directory:{}", dir, e1);
e1.printStackTrace();
}
try {
sftp.cd(dir);
log.info("Change directory {}", dir);
} catch (SftpException e1) {
log.error("Change directory failure, directory:{}", dir, e1);
e1.printStackTrace();
}
}
}
return true;
}
return false;
}
/**
* 将文件上传到指定目录
*
* @param targetPath
* @param file
* @return
* @throws Exception
*/
@Override
public boolean uploadFile(String targetPath, File file) throws Exception {
return this.uploadFile(targetPath, new FileInputStream(file));
}
/**
* 下载文件
*
* @param targetPath
* @return
* @throws Exception
*/
@Override
public File downloadFile(String targetPath) throws Exception {
ChannelSftp sftp = this.createSftp();
OutputStream outputStream = null;
try {
sftp.cd(config.getRoot());
log.info("Change path to {}", config.getRoot());
File file = new File(targetPath.substring(targetPath.lastIndexOf("/") + 1));
outputStream = new FileOutputStream(file);
sftp.get(targetPath, outputStream);
log.info("Download file success. TargetPath: {}", targetPath);
return file;
} catch (Exception e) {
log.error("Download file failure. TargetPath: {}", targetPath, e);
throw new Exception("Download File failure");
} finally {
if (outputStream != null) {
outputStream.close();
}
this.disconnect(sftp);
}
}
/**
* 删除文件
*
* @param targetPath
* @return
* @throws Exception
*/
@Override
public boolean deleteFile(String targetPath) throws Exception {
ChannelSftp sftp = null;
try {
sftp = this.createSftp();
sftp.cd(config.getRoot());
sftp.rm(targetPath);
return true;
} catch (Exception e) {
log.error("Delete file failure. TargetPath: {}", targetPath, e);
throw new Exception("Delete File failure");
} finally {
this.disconnect(sftp);
}
}
}
上一篇:Java变量和Scanner类
下一篇:Spring的核心接口
文章标题:springboot SFTP 文件上传下载功能
文章链接:http://soscw.com/index.php/essay/40890.html