使用ChannelSftp上传文件,并展示进度

前端页面

点击上传按钮后,异步递归获取文件上传进度

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="js/jquery-1.7.1.min.js"></script>
</head>
<style type="text/css">
    progress {
        background-color: #56BE64;
    }
    progress::-webkit-progress-bar {
        background: #ccc;
    }
    progress::-webkit-progress-value {
        background: #56BE64;
    }
    percentage{
        position: fixed;
        left: 160px;
    }
</style>
<body>
<h1>Spring Boot file upload example</h1>
<form id="FileuploadForm" method="POST" action="/upload" enctype="multipart/form-data">
    <input type="file" name="uploadFile" id="file"/><br />
    <br /> <input type="button" value="上传文件" onclick="upload()" />
    <div id="msg"></div>
</form>
<!--进度条部分(默认隐藏)-->
<div style="display: none" class="progress-body">
    <div>
        <progress></progress><percentage>0%</percentage>
    </div>
    <div>
        <span style="width: 100px; display: inline-block; text-align: right">上传速度:</span>
        <span style="margin-bottom: 10px; margin-left: 30px; width: 300px;" class="progress-speed">0 M/S, 0/0M</span>
    </div>
    <div>
        <span style="width: 100px; display: inline-block; text-align: right">上传状态:</span>
        <span style="margin-bottom: 10px; margin-left: 30px; width: 300px;" class="progress-info">请选择文件并点击上传文件按钮</span>
    </div>
</div>
</body>
</html>

<script>
    var percent = 0;
    // 上传文件
    function upload(){
        $("#msg").text("");
        var checkFile = $("#uploadFile").val();
        var msgInfo = "";
        if(null==checkFile || ""==checkFile){
            $("#msg").text("文件为空,请选择文件!");
        }else{
            //开始显示进度条
            showProgress();
            //递归获取上传进度
            completeHandle();
            var formData = new FormData(document.getElementById("FileuploadForm"));
            $.ajax({
                type: "POST",
                enctype:'multipart/form-data',
                url: '/myserver',
                data: formData,
                cache:false,
                processData:false,
                contentType:false,
                error:function(result){
                    console.log("error");
                    console.log(result);
                    flag = false;
                    $("#msg").text("访问服务器错误,请重试!");
                },
                success: function(result){
                    console.log("success");
                    $('.progress-body percentage').html("100.00%");
                    $('.progress-body .progress-info').html("上传文件完成。");
                    //定时,2秒后执行hideProgress方法
                    setTimeout(hideProgress, 2000);
                },
                /*从前端页面上传至后台的进度展示
                xhr: function () {
                    var xhr = $.ajaxSettings.xhr();
                    if (xhr.upload) {
                        //处理进度条的事件
                        xhr.upload.addEventListener("progress", progressHandle, false);
                        //加载完成的事件
                        xhr.addEventListener("load", completeHandle, false);
                        //加载出错的事件
                        xhr.addEventListener("error", failedHandle, false);
                        //加载取消的事件
                        xhr.addEventListener("abort", canceledHandle, false);
                        //开始显示进度条
                        showProgress();
                        return xhr;
                    }
                }*/
            }, 'json');
        }
    }



    var start = 0;
    //显示进度条的函数
    function showProgress() {
        start = new Date().getTime();
        $(".progress-body").css("display", "block");
    }
    //隐藏进度条的函数
    function hideProgress() {
        $("#uploadFile").val('');
        percent = 0;
        $('.progress-body progress').attr({value: 0, max: 0});
        $('.progress-body .progress-speed').html("0 M/S, 0/0M");
        $('.progress-body percentage').html("0%");
        $('.progress-body .progress-info').html("请选择文件并点击上传文件按钮");
        $(".progress-body").css("display", "none");
    }
    //进度条更新
    function progressHandle(e) {
      /*  $('.progress-body progress').attr({value: e.loaded, max: e.total});
        var percent = e.loaded / e.total * 100;
        var time = ((new Date().getTime() - start) / 1000).toFixed(3);
        if(time == 0){
            time = 1;
        }
        $('.progress-body .progress-speed').html(((e.loaded / 1024) / 1024 / time).toFixed(2) + "M/S, " + ((e.loaded / 1024) / 1024).toFixed(2) + "/" + ((e.total / 1024) / 1024).toFixed(2) + " MB. ");

        $('.progress-body percentage').html(percent + "%");
        if (percent == 100) {
            $('.progress-body .progress-info').html("上传完成,后台正在处理...");
        } else {
            $('.progress-body .progress-info').html("文件上传中...");
        }*/
    };
    //上传完成处理函数
/*    function completeHandle() {
        $('.progress-body .progress-info').html("上传文件完成。");
        setTimeout(hideProgress, 2000);
    };*/

    function completeHandle(){
        //if(percent == 100 ){
            //$('.progress-body .progress-info').html("上传文件完成。");
            //return;
        //}
        var url = "/getprogressMonitor";
        $.ajax({
            type: 'get',
            url: url,
            dataType: "json",
            contentType:"application/json;charset=utf-8",
            success: function(json){
                percent = json.plan;
                $('.progress-body progress').attr({value: json.transfered, max: json.fileSize});
                $('.progress-body percentage').html(percent  + "%");
                $('.progress-body .progress-info').html("上传中");
                if(son.transfered == json.fileSize && json.fileSize != 0){
                    $('.progress-body percentage').html("100%");
                    $('.progress-body .progress-info').html("上传文件完成。");
                    return;
                }
                completeHandle();
            },
            error: function(data){

            }
        });
    }
    //上传出错处理函数
    function failedHandle(e) {
        $('.progress-body .progress-info').html("上传文件出错, 服务不可用或文件过大。");
    };
    //上传取消处理函数
    function canceledHandle(e) {
        $('.progress-body .progress-info').html("上传文件取消。");
    };
</script>

工具类 FTPUtils

再上传文件时 通过实现SftpProgressMonitor接口来获取文件上传进度

import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Properties;
import java.util.Vector;

public class FTPUtils {
    private static final Logger LOG = LoggerFactory.getLogger(FTPUtil.class);

    private static ChannelSftp sftp = null;

    public FTPUtils() {
    }

    public static FTPUtils getConnect(String ftphost, String ftpusername, String ftppassword, int ftpport) {
        FTPUtils ftp = new FTPUtils();

        try {
            JSch jsch = new JSch();
            Session sshSession = jsch.getSession(ftpusername, ftphost, ftpport);
            sshSession.setPassword(ftppassword);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp)channel;
        } catch (Exception var9) {
            var9.printStackTrace();
        }

        return ftp;
    }

    public String upload(String uploadFile, String directory, String filename) {
        File file = null;
        String fileName = null;
        FileInputStream in = null;
        OutputStream outputStream = null;
        FileProgressMonitor fileProgressMonitor = null;

        try {
            sftp.cd(directory);
            file = new File(uploadFile);
            in = new FileInputStream(file);
            /*byte[] bytes = new byte[1024];
            outputStream = sftp.put(filename);
            int aa = 0;
            while ((aa = in.read(bytes)) != -1) {

                outputStream.write(bytes, 0, aa);
            }*/
            fileProgressMonitor = new FileProgressMonitor(file.length());
            sftp.put(uploadFile,filename,fileProgressMonitor,ChannelSftp.OVERWRITE);
        } catch (Exception var47) {
            var47.printStackTrace();
        } finally {
            if (in != null) {
                try {

                    in.close();
                    if(outputStream != null){
                        outputStream.close();
                    }
                } catch (IOException var45) {
                    var45.printStackTrace();
                } finally {
                    in = null;
                }
            }

        }

        return (String)(file == null ? null : fileName);
    }

    public void download(String ftpdir, String downloadFileName, String localfilepath) {
        FileOutputStream out = null;

        try {
            sftp.cd(ftpdir);
            File file = new File(localfilepath);
            out = new FileOutputStream(file);
            sftp.get(downloadFileName, out);
            out.flush();
        } catch (Exception var45) {
            var45.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException var43) {
                    var43.printStackTrace();
                } finally {
                    out = null;
                }
            }

        }

    }

    public Vector listFiles(String directory) throws SftpException {
        return sftp.ls(directory);
    }

    public void disconnect() {
        sftp.quit();
        sftp.exit();
        sftp.disconnect();
    }
}

自定义定时监听器**FileProgressMonitor **

import com.jcraft.jsch.SftpProgressMonitor;
import com.web.model.ScheduleSingLeTon;

import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class FileProgressMonitor extends TimerTask implements SftpProgressMonitor {
    // 默认间隔时间为5秒
    private long progressInterval = 5 * 1000;

    private boolean isEnd = false; // 记录传输是否结束

    private long transfered; // 记录已传输的数据总大小

    private long fileSize; // 记录文件总大小

    private ScheduledThreadPoolExecutor scheduled; // 定时器对象

    private boolean isScheduled = false; // 记录是否已启动timer记时器
    //自定义的进度单例类(前端查询进度时,返回该对象)
    //有其他好的方法欢迎留言
    ScheduleSingLeTon insteans = ScheduleSingLeTon.getInsteans();



    public FileProgressMonitor(long fileSize) {
        this.fileSize = fileSize;
        insteans.setFileSize(fileSize);

    }

    @Override
    public void run() {
        if (!isEnd()) { // 判断传输是否已结束
            System.out.println("Transfering is in progress.");
            long transfered = getTransfered();

            if (transfered != fileSize) { // 判断当前已传输数据大小是否等于文件总大小
                System.out.println("Current transfered: " + transfered + " bytes");
                sendProgressMessage(transfered);
            } else {
                System.out.println("File transfering is done.");
                setEnd(true); // 如果当前已传输数据大小等于文件总大小,说明已完成,设置end
            }
        } else {
            System.out.println("Transfering done. Cancel timer.");
            stop(); // 如果传输结束,停止timer记时器
            return;
        }
    }

    public void stop() {
        System.out.println("Try to stop progress monitor.");
        if (scheduled != null) {
            scheduled.shutdownNow();
            scheduled = null;
            isScheduled = false;
        }
        System.out.println("Progress monitor stoped.");
    }

    public void start() {
        System.out.println("Try to start progress monitor.");
        if (scheduled == null) {
            scheduled = new ScheduledThreadPoolExecutor(1);
        }
        scheduled.scheduleAtFixedRate(this,0,1000, TimeUnit.MILLISECONDS);
        insteans.setTransfered(0L);
        insteans.setPlan("0.00");
        isScheduled = true;
        System.out.println("Progress monitor started.");
    }

    /**
     * 打印progress信息
     * @param transfered
     */
    private void sendProgressMessage(long transfered) {
        if (fileSize != 0) {
            double d = ((double)transfered * 100)/(double)fileSize;
            DecimalFormat df = new DecimalFormat( "#.##");
            System.out.println("Sending progress message: " + df.format(d) + "%");

            insteans.setPlan(df.format(d));
        } else {
            System.out.println("Sending progress message: " + transfered);
        }
    }

    /**
     * 实现了SftpProgressMonitor接口的count方法
     */
    @Override
    public boolean count(long count) {
        if (isEnd()){
            return false;
        }
        if (!isScheduled) {
            start();
        }
        add(count);
        return true;
    }

    /**
     * 实现了SftpProgressMonitor接口的end方法
     */
    @Override
    public void end() {
        setEnd(true);
        insteans.setFileSize(0L);
        insteans.setTransfered(0L);
        insteans.setPlan("0.00");
        System.out.println("transfering end.");
    }

    private synchronized void add(long count) {
        transfered = transfered + count;
        insteans.setTransfered(transfered);
    }

    private synchronized long getTransfered() {
        return transfered;
    }

    public synchronized void setTransfered(long transfered) {
        this.transfered = transfered;
    }

    private synchronized void setEnd(boolean isEnd) {
        this.isEnd = isEnd;
    }

    private synchronized boolean isEnd() {
        return isEnd;
    }

    @Override
    public void init(int op, String src, String dest, long max) {
        // Not used for putting InputStream
    }
}

进程单例类ScheduleSingLeTon

public class ScheduleSingLeTon {
    private static final ScheduleSingLeTon INSTEANS = new ScheduleSingLeTon();

    private long transfered; // 记录已传输的数据总大小

    private long fileSize; // 记录文件总大小
    //进度
    private String plan ="0.00";

    public long getTransfered() {
        return transfered;
    }

    public void setTransfered(long transfered) {
        this.transfered = transfered;
    }

    public long getFileSize() {
        return fileSize;
    }

    public void setFileSize(long fileSize) {
        this.fileSize = fileSize;
    }

    public String getPlan() {
        return plan;
    }

    public void setPlan(String plan) {
        this.plan = plan;
    }

    private ScheduleSingLeTon(){

    }
    public static ScheduleSingLeTon getInsteans(){
        return INSTEANS;
    }
}

Controller

@Controller
@RequestMapping("/upload")
public class UploadCtrl {
    private static final String TMP_PATH = "f:/projects/tmp";
    ScheduleSingLeTon insteans = ScheduleSingLeTon.getInsteans();

    @RequestMapping(value = "", method = RequestMethod.GET)
    public String fileUploadInit() {
        // InfoMsg infoMsg = new InfoMsg();

        return "upload";
    }

    @RequestMapping(value = "", method = RequestMethod.POST)
    @ResponseBody
    public ResultDto fileUpload(@RequestParam("uploadFile") MultipartFile multipartFile) {
        ResultDto resultDto = new ResultDto();
        if (multipartFile.isEmpty()) {
            resultDto.setErrorCode("error");
            resultDto.setErrorMessage("Please select a file to upload");
            return resultDto;
        }

        try {

                    File localDirectorFile = new File(TMP_PATH);
                    if (localDirectorFile.isDirectory() && !localDirectorFile.exists()) {
                        localDirectorFile.mkdirs();
                    }
                    System.out.println(multipartFile.getOriginalFilename());
                    String pathName = multipartFile.getOriginalFilename();
                    FileCopyUtils.copy(multipartFile.getBytes(), new FileOutputStream(pathName));
                    FTPUtils ftpJSch = FTPUtils.getConnect("", "", "", 22);
                    int index = pathName.lastIndexOf('\\');
                    String  newPathName = pathName.substring(index+1);
                    ftpJSch.upload("", "", "");



        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultDto;
    }
    /*
     * 获取上传进度
     * */
    @GetMapping("/getprogressMonitor")
    public ScheduleSingLeTon getprogressMonitor(){
        return  insteans;
    }
}

声明:JSch - Java实现的SFTP(文件上传详解篇):http://www.cnblogs.com/longyg/archive/2012/06/25/2556576.html

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值