SpringBoot上传文件到远程服务器(二十九)
Posted 两个蝴蝶飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot上传文件到远程服务器(二十九)相关的知识,希望对你有一定的参考价值。
风,将吹拂着我们的墓碑
上一章简单介绍了SpringBoot导入和导出Csv文件(二十八),如果没有看过,请观看上一章
前两个章节,我们学习了上传文件到本地服务器,这一章节,老蝴蝶和大家一起,上传文件到远程服务器.
上传文件到远程服务器,可以通过 FTP 或者 SSH 技术.
本章节的技术,依赖于 hutool 技术
关于 SSH 的技术,可以查看文档: Jsch(SSH)工具-JschUtil
关于 FTP 的技术,可以查看文档: FTP客户端封装-Ftp
本文章 采用 一个接口,两个实现 (SSH实现和 FTP实现) 的方式,进行演示.
一定要先学习一下,老蝴蝶写的: SpringBoot自定义Starter(二十四) 文章内容
本章节的代码目录结构如下:
一. FTP和SSH 实现文件上传和下载公共配置
一. 一 pom.xml 添加依赖
<!--添加hutools工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.5</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
一.二 配置文件进行配置
application.yml 配置文件
server:
port: 7011
servlet:
context-path: /File
# 进行配置
file:
useftp: true # 是否使用 ftp, 为false表示使用 ssh上传
ssh:
host: 192.168.56.103 #已经配置了 ftp服务
port: 21
username: ftpuser #对应的用户名和密码
password: ftpuser
uploadFilePath: /home/ftpuser/ #上传文件的路径
downloadFilePath: D:/ #下载到哪个文件
spring:
# 配置thymeleaf的相关信息
thymeleaf:
# 开启视图解析
enabled: true
#编码格式
encoding: UTF-8
#前缀配置
prefix: classpath:/templates/
# 后缀配置
suffix: .html
#是否使用缓存 开发环境时不设置缓存
cache: false
# 格式为 HTML 格式
mode: HTML5
# 配置类型
servlet:
content-type: text/html
#配置上传的文件信息
servlet:
multipart:
max-file-size: 100MB # 服务器端文件大小限制
max-request-size: 100MB # 客户端请求文件大小限制
profiles:
# 配置谁生效
active: ftp # 注意这一个属性,表示哪一个实现被使用到
一.三 用属性类接收 file部分的配置内容
在 pojo 包下,添加配置类 SshFileProperties.java , 用于接收配置的属性
@Data
@Component
@ConfigurationProperties(prefix ="file.ssh" )
public class SshFileProperties
private static final String DEFAULT_HOST="127.0.0.1";
private static final Integer DEFAULT_PORT=22;
private static final String DEFAULT_USERNAME="";
private static final String DEFAULT_PASSWORD="";
private static final String DEFAULT_UPLOAD_FILEPATH="/usr/local/";
private static final String DEFAULT_DOWNLOAD_FILEPATH="/usr/local/";
private String host=DEFAULT_HOST;
private Integer port=DEFAULT_PORT;
private String username=DEFAULT_USERNAME;
private String password=DEFAULT_PASSWORD;
private String uploadFilePath=DEFAULT_UPLOAD_FILEPATH;
private String downloadFilePath=DEFAULT_DOWNLOAD_FILEPATH;
一.四 配置接口
创建接口 FileService.java
public interface FileService
/**
* 上传文件
* @date 2021/11/5 11:52
* @author zk_yjl
* @param file 上传的文件
* @param path 上传的文件的名称
* @return String 上传后文件的路径
*/
default String upload(String dest,String name,File file)
return dest+name;
/**
* 上传文件
* @date 2021/11/5 11:52
* @author zk_yjl
* @param file 上传的文件
* @param path 上传的文件的名称
* @return String 上传后文件的路径
*/
default String pathUpload(String path,File file)
return path;
/**
* 下载文件
* @date 2021/11/5 11:54
* @author zk_yjl
* @param fileName 下载的文件名称
* @param outFile 下载到的文件
* @return void
*/
default void download(String dest,String fileName,File outFile)
/**
* 下载文件,以绝对路径进行下载.
* @date 2021/11/5 11:54
* @author zk_yjl
* @param path 下载的文件的路径
* @param outFile 下载到的文件
* @return void
*/
default void pathDownload(String path,File outFile)
二. FTP 和 SSH 接口实现
二. 一 FTP 配置
主要是一个工具类 FtpUtil
@Configuration
@Log4j2
public class FtpUtil
@Autowired
private SshFileProperties sshFileProperties;
@Value("$file.useftp")
private Boolean useftp;
/**
* 创建连接
* @date 2021/11/5 17:21
* @author zk_yjl
* @param
* @return org.apache.commons.net.ftp.FTPClient
*/
public FTPClient createFileClient()
if(!useftp)
return null;
FTPClient ftpClient=new FTPClient();
try
ftpClient.setControlEncoding("gbk");
ftpClient.connect(sshFileProperties.getHost(), sshFileProperties.getPort());
ftpClient.login(sshFileProperties.getUsername(), sshFileProperties.getPassword());
ftpClient.enterLocalPassiveMode();
// 设置上传目录
ftpClient.setBufferSize(1024);
ftpClient.setConnectTimeout(10 * 1000);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
return ftpClient;
catch (Exception e)
log.error("创建FTP服务器失败,",e);
return ftpClient;
/**
* 关闭连接
* @date 2021/11/5 17:21
* @author zk_yjl
* @param ftpClient
* @return void
*/
public void close(FTPClient ftpClient)
try
if(ftpClient!=null)
ftpClient.disconnect();
catch (IOException e)
throw new RuntimeException("关闭FTP连接发生异常!", e);
二.二 SSH配置
主要是一个配置类 SftpConfig
@Configuration
public class SftpConfig
@Autowired
private SshFileProperties sshFileProperties;
@Value("$file.useftp")
private Boolean useftp;
@Bean
public Sftp getSftp()
if(useftp)
return null;
return createSftp(
sshFileProperties.getHost(), sshFileProperties.getPort(), sshFileProperties.getUsername(), sshFileProperties.getPassword());
@Bean
public Session getSession()
if(useftp)
return null;
return createSession(sshFileProperties.getHost(),
sshFileProperties.getPort(),
sshFileProperties.getUsername(),
sshFileProperties.getPassword());
public static Sftp createSftp(String sshHost, int sshPort, String sshUser, String sshPass)
return JschUtil.createSftp(sshHost, sshPort, sshUser, sshPass);
public static Session createSession(String sshHost, int sshPort, String sshUser, String sshPass)
return JschUtil.getSession(sshHost, sshPort, sshUser, sshPass);
二.三 通过不同的环境,选择不同的实现
@Configuration
public class JavaConfig
@Autowired(required = false)
private Sftp sftp;
@Autowired(required = false)
private FtpUtil ftpUtil;
/**
条件符合时,创建
*/
@Bean("fileService")
@Profile("ftp")
FileService ftp()
return new FtpFileServiceImpl(ftpUtil);
/**
条件符合时,创建
*/
@Bean("fileService")
@Profile("sftp")
FileService cat()
return new SftpFileServiceImpl(sftp);
二.四 不同的实现
二.四.一 FTP 实现
FtpFileServiceImpl.java
@Log4j2
public class FtpFileServiceImpl implements FileService
private FtpUtil ftpUtil;
public FtpFileServiceImpl(FtpUtil ftpUtil)
this.ftpUtil=ftpUtil;
@Override
public String upload(String dest,String fileName, File file)
if(StringUtils.isEmpty(fileName))
fileName=file.getName();
FTPClient ftpClient=null;
//切换到相应的目录
try
ftpClient=ftpUtil.createFileClient();
boolean isExistDir = ftpClient.changeWorkingDirectory(dest);
if(!isExistDir)
ftpClient.makeDirectory(dest);
ftpClient.changeWorkingDirectory(dest);
//保存文件
ftpClient.storeFile(fileName,new FileInputStream(file));
log.info("上传文件成功");
return dest+fileName;
catch (Exception e)
log.error("上传文件失败,",e);
finally
ftpUtil.close(ftpClient);
return null;
@Override
public String pathUpload(String path, File file)
//切换到相应的目录
String[] split = path.split(File.separator);
int size=split.length;
FTPClient ftpClient=null;
try
ftpClient=ftpUtil.createFileClient();
for (int i=0;i<size-2;i++)
String tempPath=split[i];
if (StringUtils.isEmpty(tempPath))
continue;
if (!ftpClient.changeWorkingDirectory(tempPath))
ftpClient.makeDirectory(tempPath);
ftpClient.changeWorkingDirectory(tempPath);
//保存文件
ftpClient.storeFile(split[size-1],new FileInputStream(file));
log.info("上传文件成功");
return path;
catch (Exception e)
log.error("上传文件失败,",e);
finally
ftpUtil.close(ftpClient);
return null;
@Override
public void download(String dest,String fileName, File outFile)
pathDownload(dest+fileName,outFile);
@Override
public void pathDownload(String path, File outFile)
FTPClient ftpClient=null;
try
ftpClient=ftpUtil.createFileClient();
ftpClient.retrieveFile(path,new FileOutputStream(outFile));
catch (IOException e)
e.printStackTrace();
finally
ftpUtil.close(ftpClient);
二.四.二 SFTP 实现
@Log4j2
public class SftpFileServiceImpl implements FileService
private Sftp sftp;
public SftpFileServiceImpl(Sftp sftp)
this.sftp=sftp;
@Override
public String upload(String dest,String fileName, File file)
if(StringUtils.isEmpty(fileName))
fileName=file.getName();
try
sftp.cd(dest);
catch (Exception e)
log.info("该文件夹不存在,自动创建");
sftp.mkdir(dest);
try
sftp.getClient().put(
new FileInputStream(file),
dest+fileName
);
log.info(">>>文件上传成功");
return dest+fileName;
catch (Exception e)
log.error("文件上传失败,",e);
return null;
@Override
public String pathUpload(String path, File file)
try
sftp.getClient().put(new FileInputStream(file),path);
catch (Exception e)
log.error("文件上传失败,",e);
return null;
return null;
@Override
public void download(String dest,String fileName, File outFile)
sftp.download(dest+fileName,outFile);
@Override
public void pathDownload(String path, File outFile)
sftp.download(path,outFile);
二.五 controller 控制器
@Controller
public class FileController
@Autowired
private FileService fileService;
@Autowired
private SshFileProperties sshFileProperties;
@RequestMapping("/")
public String index()
return "index";
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile file, HttpServletRequest request) throws IOException
// 获得 classpath 的绝对路径
String realPath = ResourceUtils.getURL("classpath:").getPath()+"static/files";
File newFile = new File(realPath);
// 如果文件夹不存在、则新建
if (!newFile.exists())
以上是关于SpringBoot上传文件到远程服务器(二十九)的主要内容,如果未能解决你的问题,请参考以下文章
第二十九章 springboot + zipkin + mysql