风,将吹拂着我们的墓碑
上一章简单介绍了SpringBoot导入和导出Csv文件(二十八),如果没有看过,请观看上一章
前两个章节,我们学习了上传文件到本地服务器,这一章节,老蝴蝶和大家一起,上传文件到远程服务器.
上传文件到远程服务器,可以通过 FTP 或者 SSH 技术.
本章节的技术,依赖于 hutool 技术
关于 SSH 的技术,可以查看文档: Jsch(SSH)工具-JschUtil
关于 FTP 的技术,可以查看文档: FTP客户端封装-Ftp
本文章 采用 一个接口,两个实现 (SSH实现和 FTP实现) 的方式,进行演示.
一定要先学习一下,老蝴蝶写的: SpringBoot自定义Starter(二十四) 文章内容
本章节的代码目录结构如下:
一. FTP和SSH 实现文件上传和下载公共配置 一. 一 pom.xml 添加依赖一.二 配置文件进行配置cn.hutool hutool-all 5.7.5 commons-net commons-net 3.6 com.jcraft jsch 0.1.54
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 { default String upload(String dest,String name,File file){ return dest+name; } default String pathUpload(String path,File file){ return path; } default void download(String dest,String fileName,File outFile){ } 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; 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; } 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二.四.二 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()){ newFile.mkdirs(); } // 上传 File uploadFile=new File(newFile, file.getOriginalFilename()); file.transferTo(uploadFile); String uploadPath = fileService.upload(sshFileProperties.getUploadFilePath(),file.getOriginalFilename(), uploadFile); //将以前的文件删除掉 uploadFile.delete(); return "上传文件成功,地址为:"+uploadPath; } @GetMapping("download") @ResponseBody public String download(String fileName) throws IOException { // 获得待下载文件所在文件夹的绝对路径 String realPath =sshFileProperties.getUploadFilePath(); //构建新的文件 File downloadDirFile=new File(sshFileProperties.getDownloadFilePath()); // 如果文件夹不存在、则新建 if (!downloadDirFile.exists()){ downloadDirFile.mkdirs(); } // 上传 File downloadFile=new File(downloadDirFile,fileName); String downloadPath=sshFileProperties.getDownloadFilePath()+fileName; fileService.download(realPath,fileName,downloadFile); return "文件下载成功,下载后的目录为:"+downloadPath; } }前端与以前的是一致的.
三. FTP 上传和下载 三.一 搭建 FTP 服务器可以按照 这个网址 进行搭建 FTP 服务器
https://help.aliyun.com/document_detail/92048.html
配置后,可以权限不太好控制,直接使用
anonymous_enable=NO local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES xferlog_enable=YES connect_from_port_20=YES xferlog_std_format=YES listen=YES pam_service_name=vsftpd userlist_enable=YES tcp_wrappers=YES全部替换 /etc/vsftpd/vsftpd.conf 里面的内容
通过 FileZilla 进行连接,是成功的.
三.二 配置applicaiton.yml 里面有两个配置信息
# 进行配置 file: useftp: true #配置成true ssh: host: 192.168.56.103 #配置ftp服务器的相关信息 port: 21 username: ftpuser password: ftpuser uploadFilePath: /home/ftpuser/ #上传到哪个目录下,该用户必须有这个目录的修改权限 downloadFilePath: D:/还有最后一段, 配置成 ftp
spring: profiles: # 配置谁生效 active: ftp三.三 上传和下载文件演示先将 yjl.p12 文件进行删除
启动服务器
进行上传文件:
刷新一下ftp 服务器,发现文件上传了上去
点击文件下载按钮,进行下载操作
查看时间,发现是刚才下载的那个文件.
FTP 服务器上传是成功的.
四. SSH 上传和下载 四.一 配置applicaiton.yml 里面有两个配置信息
# 进行配置 file: useftp: false ssh: host: 192.168.56.103 port: 22 username: root #服务器的用户名 password: abc123 # 服务器的密码 uploadFilePath: /usr/local/ downloadFilePath: D:/还有最后一段, 配置成 ftp
spring: profiles: # 配置谁生效 active: sftp四.二 上传和下载文件通过 Xshell 连接上服务器, 查看 /usr/local 下的目录文件
此时是没有 yjl.p12 文件的
刷新一下目录,看是否上传文件成功
文件是上传成功的 (时间不对,是因为老蝴蝶我服务器本身的时间就是错误的)
进行下载
查看磁盘文件
文件是下载成功的。
本章节的代码放置在 github 上:
https://github.com/yuejianli/springboot/tree/develop/SpringBoot_SSH_File
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!