SpringBoot上传文件到远程服务器(二十九)

SpringBoot上传文件到远程服务器(二十九),第1张

SpringBoot上传文件到远程服务器(二十九)

风,将吹拂着我们的墓碑

上一章简单介绍了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

谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5503700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-13
下一篇 2022-12-13

发表评论

登录后才能评论

评论列表(0条)

保存