vue下载FTP文件的前后端代码(在浏览器下载)

722 阅读3分钟

1、前端代码

image.png

1.1、请求参数添加以下代码

responseType: 'blob'

1.2、请求后端代码,返回结果的处理

downloadFtp('\/wangzhan\/Snipaste_2022-07-26_14-04-58.png').then((response) => {

    let blob = new Blob([response]);
    const downUrl = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.style.display = "none";
    link.href = downUrl;
    link.target = "_blank";
    link.download = "Snipaste_2022-07-26_14-04-58.png";
    document.body.appendChild(link);
    link.click();
    link.remove();
    URL.revokeObjectURL(downUrl); // 释放掉blob对象
})

2、后端代码

2.1、工具类 - FTPUtils

package com.evimage.web.evgis.ftp;

import com.evimage.common.utils.uuid.UUID;
import lombok.Data;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * 
 * @description: FTP工具对象
 * @author: wangzhan
 * @create: 2022-07-01 11:50
 **/
@Component
@Data
public class FTPUtils {

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

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

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

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

    private FTPClient ftpClient = null;

    /**
     * 连接FTP服务器
     */
    public void getFtpConnect(){
        ftpClient = new FTPClient();
        try {
            ftpClient.setControlEncoding("GBK");
            ftpClient.connect(host, port);
            ftpClient.login(username, password);
            int reply = ftpClient.getReplyCode();

            if (!FTPReply.isPositiveCompletion(reply)) {
                closeConnect();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 关闭ftp链接
     */
    public void closeConnect() {
        try {
            ftpClient.logout();
            if (ftpClient.isConnected()) {
                ftpClient.disconnect();
            }
            this.ftpClient = null;
        } catch (IOException e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

    /**
     * 判断路径是否存在,存在则改变工作目录
     * @param path
     * @return
     */
    public boolean isDirExist(String path){
        boolean flag = false;
        try {
            flag = ftpClient.changeWorkingDirectory(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 逐级创建工作目录,并跳转到工作目录中
     * @param path
     */
    public void mkdirAndChangeWorkingDirectory(String path){
        for (String str : path.split("/")) {
            if(StringUtils.isBlank(str)) {
                continue;
            }
            try {
                if (!ftpClient.changeWorkingDirectory(str)) {
                    // 创建目录
                    ftpClient.makeDirectory(str);
                    // 改变目录
                    ftpClient.changeWorkingDirectory(str);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 下载文件
     * @param path
     * @return
     */
    public File download(String path) throws IOException {

        InputStream inputStream = null;
        File file = new File(String.valueOf(UUID.randomUUID()));

        try {
            //将设置文件编码
            ftpClient.setControlEncoding(StandardCharsets.UTF_8.name());
            //将设置文件传输模式为二进制,可以保证传输的内容不会被改变
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

            // 下载文件
            inputStream = ftpClient.retrieveFileStream(path);

            FileUtils.copyInputStreamToFile(inputStream, file);

            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return file;
    }

    /**
     * 将文件上传到ftp上
     * @param file  需要上传的文件
     * @param path  ftp中文件的路径
     * @param fileName  文件名字
     * @return  返回文件存放路径
     */
    public String upload(MultipartFile file, String path, String fileName){

        try {
            //进入本地被动模式
            ftpClient.enterLocalPassiveMode();
            //将设置文件传输模式为二进制,可以保证传输的内容不会被改变
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            //storeFile 上传FTP
            boolean flag = ftpClient.storeFile(fileName, file.getInputStream());

            if (!flag){
                throw new RuntimeException("FTP上传失败!");
            }else {
                System.out.println(fileName+"上传成功");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return path + "/" + fileName;
    }

}

2.2、工具类 - HttpsUtils

package com.evimage.web.evgis.ftp;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * 
 * @description: https相关操作
 * @author: wangzhan
 * @create: 2022-06-22 11:17
 **/

public class HttpsUtils {

    /**
     * 输入文件流及文件名称返回给浏览器下载
     * @param response  浏览器响应对象
     * @param fileInputStream   文件流
     * @param fileName  文件名称
     */
    public static void HttpsDownload(HttpServletResponse response, FileInputStream fileInputStream, String fileName){
        try{
            // 文件路径及名称分割
            String[] split = fileName.split("/");

            //  清空response
            response.reset();
            //Content-Disposition的作⽤:告知浏览器以何种⽅式显⽰响应返回的⽂件,⽤浏览器打开还是以附件的形式下载到本地保存表⽰以附件⽅式下载
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(split[split.length - 1], "UTF-8"));
            //告知浏览器⽂件的⼤⼩
            response.addHeader("Content-Length", ""+fileInputStream.available());
            response.addHeader("Access-Control-Allow-Origin", "*");
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream;charset=UTF-8");
            byte[] buffer = new byte[2048];
            int bytesRead = -1;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            fileInputStream.close();
            outputStream.write(buffer);
            outputStream.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public static void HttpsReview(HttpServletResponse response, InputStream inputStream,String filename){
        try{
            //  清空response
            response.reset();
            //设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作⽤:告知浏览器以何种⽅式显⽰响应返回的⽂件,⽤浏览器打开还是以附件的形式下载到本地保存表⽰以附件⽅式下载
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            //告知浏览器⽂件的⼤⼩
            response.addHeader("Content-Length", "" + inputStream.available());
            response.addHeader("Access-Control-Allow-Origin", "*");
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            byte[] buffer = new byte[2048];
            int bytesRead = -1;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

2.3、配置文件 - application.yml

image.png

ftp:
  host: 
  port: 21
  username: evFTP
  password: evFTP

2.4、controller代码

image.png

@Autowired
private FTPUtils ftpUtils;

@PostMapping("downloadFtp")
public void downloadFtp(@RequestParam("fileName") String fileName, HttpServletResponse response){
    try {
        // 获取连接
        ftpUtils.getFtpConnect();

        // 去FTP中查找文件并返回
        File file = ftpUtils.download(fileName);

        FileInputStream fileInputStream = new FileInputStream(file);

        HttpsUtils.HttpsDownload(response, fileInputStream, fileName);

        // 关闭流
        fileInputStream.close();
        file.delete();

        // 关闭连接
        ftpUtils.closeConnect();

    }catch (Exception e){
        System.out.println("异常信息:" + e.getMessage());
    }
}