Springboot通过SFTP上传文件到服务器

流程是这样的:

前端选择文件上传-------->调用后台接口,后台连接服务器(Linux)--------->上传成功

 前端无论是通过ajax,还是form表单直接提交都可以,这里暂时以form方式提交 这里需要依靠一个Sftps的工具类


先导入依赖

<dependency>
	<groupId>com.jcraft</groupId>
	<artifactId>jsch</artifactId>
	<version>0.1.54</version>
</dependency>

Sftps.java:

public final class Sftps {

    private static final Logger log = LoggerFactory.getLogger(Sftps.class);

    private Session sshSession;

    private ChannelSftp sftp;

    /**
     * 连接sftp服务器
     * @param host
     * @param port
     * @param username
     * @param password
     * @return
     * @throws Exception
     */
    public ChannelSftp connect(String host, int port, String username, String password) throws Exception {
        JSch jsch = new JSch();
        sshSession = jsch.getSession(username, host, port);

        log.debug("Session created.");

        sshSession.setPassword(password);
        Properties sshConfig = new Properties();
        sshConfig.put("StrictHostKeyChecking", "no");
        sshSession.setConfig(sshConfig);
        sshSession.connect();

        log.debug("Session connected.");
        log.debug("Opening Channel.");

        Channel channel = sshSession.openChannel("sftp");
        channel.connect();
        sftp = (ChannelSftp) channel;

        log.debug("Connected to " + host + ".");

        return sftp;
    }
    /**
     * 连接sftp服务器
     * @param host
     * @param port
     * @param username
     * @param privateKey
     * @param passphrase
     * @return
     * @throws Exception
     */
    public ChannelSftp connect(String host, int port, String username, String privateKey ,String passphrase) throws Exception {
        JSch jsch = new JSch();

        //设置密钥和密码
        if (!StringUtils.isEmpty(privateKey)) {
            if (!StringUtils.isEmpty(passphrase)) {
                //设置带口令的密钥
                jsch.addIdentity(privateKey, passphrase);
            } else {
                //设置不带口令的密钥
                jsch.addIdentity(privateKey);
            }
        }
        sshSession = jsch.getSession(username, host, port);

        log.debug("Session created.");

        Properties sshConfig = new Properties();
        sshConfig.put("StrictHostKeyChecking", "no");
        sshSession.setConfig(sshConfig);
        sshSession.connect();

        log.debug("Session connected.");
        log.debug("Opening Channel.");

        Channel channel = sshSession.openChannel("sftp");
        channel.connect();
        sftp = (ChannelSftp) channel;

        log.debug("Connected to " + host + ".");

        return sftp;
    }

    public void portForwardingL(int lport, String rhost, int rport) throws Exception {
        int assinged_port = sshSession.setPortForwardingL(lport, rhost, rport);
        System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport);
    }
    /**
     * 断开连接
     */
    public void disconnect() {
        if (sftp != null) sftp.disconnect();
        if (sshSession != null) sshSession.disconnect();
    }
    /**
     * 上传文件
     *
     * @param directory
     *            上传的目录
     * @param uploadFile
     *            要上传的文件
     * @param sftp
     */
    public void upload(String directory, String uploadFile) throws Exception {
        sftp.cd(directory);
        File file = new File(uploadFile);
        sftp.put(new FileInputStream(file), file.getName());
    }

    public void upload(String directory, File file) throws Exception {
        sftp.cd(directory);
        sftp.put(new FileInputStream(file), file.getName());
        System.out.println("upload file "+file.getAbsolutePath() + " to host " + sshSession.getHost());
    }
    //利用流上传文件 fileName
    public void uploadfileInputStream(MultipartFile file, String directory, String fileName) throws Exception {
        sftp.cd(directory);
        sftp.put(file.getInputStream(),fileName);
    }
    public void uploadDir(File src, String dst) throws Exception{
        if (!exist(dst)) {
            sftp.mkdir(dst);
        }
        if (src.isFile()) {
            upload(dst, src);
        } else {
            for (File file : src.listFiles()) {
                if (file.isDirectory()) {
                    uploadDir(file, dst + "/" + file.getName());
                }
                upload(dst, file);
            }
        }
    }
    /**
     * 目录是否查找
     * @param path
     * @return
     * @throws SftpException
     */
    public boolean exist(String path) throws SftpException {
        String pwd = sftp.pwd();
        try {
            sftp.cd(path);
        } catch (SftpException e) {
            if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
                return false;
            } else {
                throw e;
            }
        } finally {
            sftp.cd(pwd);
        }

        return true;
    }
    /**
     * 下载文件
     * @param directory
     * @param downloadFile
     * @param saveFile
     * @throws Exception
     */
    public void download(String directory, String downloadFile, String saveFile) throws Exception {
        sftp.cd(directory);
        File file = new File(saveFile);
        sftp.get(downloadFile, new FileOutputStream(file));
    }

    /**
     * 下载文件
     * @param directory
     * @param downloadFile
     * @param saveFile
     * @throws Exception
     */
    public void download(String directory, String downloadFile, File saveFile) throws Exception {
        sftp.cd(directory);
        sftp.get(downloadFile, new FileOutputStream(saveFile));
        System.out.println("download file "+directory + "/" +downloadFile + " from host " + sshSession.getHost());
    }

    /**
     * 下载文件
     * @param src
     * @param dst
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public void downloadDir(String src, File dst) throws Exception {
        try {
            sftp.cd(src);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        dst.mkdirs();

        Vector<LsEntry> files = sftp.ls(src);
        for (LsEntry lsEntry : files) {
            if (lsEntry.getFilename().equals(".") || lsEntry.getFilename().equals("..")) {
                continue;
            }
            if (lsEntry.getLongname().startsWith("d")) {
                downloadDir(src + "/" + lsEntry.getFilename(), new File(dst, lsEntry.getFilename()));
            } else {
                download(src, lsEntry.getFilename(), new File(dst, lsEntry.getFilename()));
            }

        }
    }

    /**
     *  删除文件
     * @param directory
     * @param deleteFile
     * @throws SftpException
     */
    public void delete(String directory, String deleteFile) throws SftpException {
        sftp.cd(directory);
        sftp.rm(deleteFile);
    }

    /**
     * 列出目录下的文件
     * @param directory
     * @return
     * @throws SftpException
     */
    public Vector listFiles(String directory) throws SftpException {
        return sftp.ls(directory);
    }

    public Session getSshSession() {
        return sshSession;
    }
    public ChannelSftp getSftp() {
        return sftp;
    }
}

在这个工具类里,我自己在这个类的基础之上往里面加了一个方法,利用流上传文件

//利用流上传文件 fileName
    public void uploadfileInputStream(MultipartFile file, String directory, String fileName) throws Exception {
        sftp.cd(directory);
        sftp.put(file.getInputStream(),fileName);
    }

这里要注意的是form表单中一定要添加 enctype="multipart/form-data"不然在后台接收不到文件流

<form class="form-horizontal" action="/upload" name="upload" id="form" method="post" enctype="multipart/form-data">
        <input type="file" name="filename" id="filename"/><br/>
        <input type="submit" value="提交" /><br/>
</form>

 后端Controller

@RequestMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("fileName") String fileName) throws Exception {
        if(file.isEmpty()||fileName.isEmpty()){
            new Exception("未接收到指定参数");
            return "";
        }else{
            SftpsEntity sftpsAll = service.findAll();
            try {
                sftps = new Sftps();
                //连接服务器
                sftps.connect("192.168.1.154", 22,"root","123456");
                //上传到服务器的位置
                sftps.uploadfileInputStream(file, "/", fileName);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                sftps.disconnect();
            }
            return "{message:\"上传成功\"}";
        }

 uploadfileInputStream()三个参数分别代表

file 文件流(文件),

/  代表存在服务器的根目录下,

fileName 文件全名称,包括后缀,三者缺一不可!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值