Java下载FTP文件并通过response流实现浏览器下载

Java实现FTP文件下载

    • 1.后端实现
    • 2.前端实现

1.后端实现

package com.harvey.ftp.util;

import org.apache.commons.net.ftp.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;


/**
 * 类说明:文件上传下载工具类
 *
 */
@Component
public class FtpOperation{
    /** 日志对象 */
    private static final Logger LOGGER = LoggerFactory.getLogger(FtpOperation.class);

    @Value("${ftp.username}")
    private String userName;

    @Value("${ftp.password}")
    private String passWord;

    @Value("${ftp.host}")
    private String ip;

    @Value("${ftp.port}")
    private int port;

    // ftp客户端
    private FTPClient ftpClient = new FTPClient();

    /**
     *
     * 功能:根据文件名称,下载文件流
     * @param fileDir 文件地址
     * @param filename 文件名
     * @return
     * @throws IOException
     */
    public void download(String fileDir, String filename, HttpServletResponse response) throws IOException {
        // 获取ftp信息
        String[] ftpStrs = fileDir.split(":");
        if (ftpStrs.length > 0){
            ip = ftpStrs[0];
            port = Integer.parseInt(ftpStrs[1]);
            userName = ftpStrs[2];
            passWord = ftpStrs[3];
        }
        // 获取文件名称
        String[] strs = filename.split("/");
        String downloadFile = strs[strs.length - 1];
        try {
        	// 设置文件ContentType类型,这样设置,会自动判断下载文件类型
            response.setContentType("application/x-msdownload");
            // 设置文件头:最后一个参数是设置下载的文件名并编码为UTF-8
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(downloadFile, "UTF-8"));
            // 建立连接
            connectToServer();
            ftpClient.enterLocalPassiveMode();
            // 设置传输二进制文件
            int reply = ftpClient.getReplyCode();
            ftpClient.changeWorkingDirectory("./home/ftp");
            if(!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                throw new IOException("failed to connect to the FTP Server:"+ip);
            }
            // 此句代码适用Linux的FTP服务器
            String newPath = new String(filename.getBytes("GBK"),"ISO-8859-1");
            // ftp文件获取文件
            InputStream is = null;
            BufferedInputStream bis = null;
            try {
                is = ftpClient.retrieveFileStream(newPath);
                bis = new BufferedInputStream(is);
                OutputStream out = response.getOutputStream();
                byte[] buf = new byte[1024];
                int len = 0;
                while ((len = bis.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                closeConnect();
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (FTPConnectionClosedException e) {
            LOGGER.error("ftp连接被关闭!", e);
            throw e;
        } catch (Exception e) {
            LOGGER.error("ERR : upload file "+ filename+ " from ftp : failed!", e);
        }
    }

    /**
     *
     * 功能:关闭连接
     */
    public void closeConnect() {
        try {
            if (ftpClient != null) {
                ftpClient.logout();
                ftpClient.disconnect();
            }
        } catch (Exception e) {
            LOGGER.error("ftp连接关闭失败!", e);
        }
    }

    /**
     * 连接到ftp服务器
     */
    private void connectToServer() throws Exception {
        if (!ftpClient.isConnected()) {
            int reply;
            try {
                ftpClient=new FTPClient();
                ftpClient.connect(ip,port);
                ftpClient.login(userName,passWord);
                reply = ftpClient.getReplyCode();

                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftpClient.disconnect();
                    LOGGER.info("connectToServer FTP server refused connection.");
                }

            }catch(FTPConnectionClosedException ex){
                LOGGER.error("服务器:IP:"+ip+"没有连接数!there are too many connected users,please try later", ex);
                throw ex;
            }catch (Exception e) {
                LOGGER.error("登录ftp服务器【"+ip+"】失败", e);
                throw e;
            }
        }
    }
}

2.前端实现

<html>
<head>
	<style>
	</style>
	<script src="jquery-3.4.1.min.js"></script>
	<script>
	function downLoad(param1, param2) {
    var xhr = new XMLHttpRequest();
    var url = "http://localhost:8080/ftp/download?fileDir=" + param1 + "&filename=" + param2;
    xhr.open('GET', url, true);
	xhr.responseType = "blob";
    xhr.send();
	
    xhr.onload = function() {
	var aName = xhr.getResponseHeader('Content-Disposition').split('=')[1];

	const data = xhr.response;
    const a = document.createElement('a');
    const blob = new Blob([data],{ type: 'application/force-download' });
    const blobUrl = window.URL.createObjectURL(blob);
    download2(blobUrl,aName) ;
    }
}
function download2(blobUrl,aName){
const a = document.createElement('a');

  a.style.display = 'none';
  a.download = decodeURIComponent(aName);
  a.href = blobUrl;
  a.click();
  document.body.removeChild(a);

}
	</script>
</head>
<body>

<div >
	<a href ="javascript:void(0)" onclick="downLoad('ip地址:端口号:账号:密码:./home/ftp/测试.doc')">下载</a>
</div>

</body>
</html>

你可能感兴趣的:(Java)