springboot整合FTP实现在controller层的下载

一:描述

作者有一个需求,文件是存在FTP服务器中,然后在controller层写代码实现下载,可惜在其它网站上找到的都是下载到指定路径,无法实现在页面上显示下载的效果,作者经过多方查询资料整合后,终于完成功能,现分享给大家.

二:实现步骤

1,新建一个FtpUtil(Ftp工具类)

内容如下:

package com.foxconn.dcc.utils;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.util.HashMap;

/**
 * @ClassName: FtpUtil
 * @Description: FTP工具类
 * @Author rookie
 * @date 2020/5/6 10:41
 * @Version: 1.0
 **/
public class FtpUtil {
    /**
     * FTP服务器hostname(需要修改此处)
     */
    private static String HOST = "10.32.123.123";
    /**
     * FTP服务器端口(默认21)
     */
    private static int PORT = 21;
    /**
     * FTP登录账号(需要修改此处)
     */
    private static String USERNAME = "ftpService";
    /**
     * FTP登录密码(需要修改此处)
     */
    private static String PASSWORD = "a123456789";
    /**
     * FTP服务器基础目录(不要修改此处)
     */
    private static String BASEPATH = "";
    /**
     * FTP客户端
     */
    private static FTPClient ftp;

    /**
     * @Description 初始化FTP客户端
     * @Author rookie
     * @date 2020/5/6 10:41
     * @Param []
     * @return boolean
     **/
    public static boolean initFtpClient(){
        ftp = new FTPClient();
        int reply;
        try {
            // 连接FTP服务器
            ftp.connect(HOST, PORT);
            //登录, 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(USERNAME, PASSWORD);
            ftp.setBufferSize(10240);
            //设置传输超时时间为60秒
            ftp.setDataTimeout(600000);
            //连接超时为60秒
            ftp.setConnectTimeout(600000);
            //FTP以二进制形式传输
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }


    /**
     * Description: 向FTP服务器上传文件
     * @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
     * @param filename 上传到FTP服务器上的文件名
     * @param input 本地要上传的文件的 输入流
     * @return 成功返回true,否则返回false
     */
    public static boolean uploadFile(String filePath, String filename, InputStream input) {
        boolean result = false;
        try {
            filePath = new String(filePath.getBytes("GBK"),"iso-8859-1");
            filename = new String(filename.getBytes("GBK"),"iso-8859-1");
             if (!initFtpClient()){
                 return result;
             };
            //切换到上传目录
            ftp.enterLocalPassiveMode();
            if (!ftp.changeWorkingDirectory(BASEPATH+filePath)) {
                //如果目录不存在创建目录
                String[] dirs = filePath.split("/");
                String tempPath = BASEPATH;
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir)){
                        continue;
                    }
                    tempPath += "/" + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {
                        if (!ftp.makeDirectory(tempPath)) {
                            return result;
                        } else {
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            //设置上传文件的类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            //上传文件
            ftp.enterLocalPassiveMode();
            if (!ftp.storeFile(filename, input)) {
                return result;
            }
            input.close();
            ftp.logout();
            result = true;
        }
        catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }


   /**
     * @Description 从ftp服务器下载文件到指定输出流
     * @Author andrew
     * @Date 22:30 2020/3/5
     * @Param [remotePath, fileName, outputStream]
     * @return boolean
     **/
    public static boolean downloadFile(String remotePath, String fileName, OutputStream outputStream) {
        boolean result = false;
        try {
            remotePath = new String(remotePath.getBytes("GBK"),"iso-8859-1");
            fileName = new String(fileName.getBytes("GBK"),"iso-8859-1");
            if (!initFtpClient()){
                return result;
            };
            // 转移到FTP服务器目录
            ftp.changeWorkingDirectory(remotePath);
            ftp.enterLocalPassiveMode();
            FTPFile[] fs = ftp.listFiles();
            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    ftp.enterLocalPassiveMode();
                    ftp.retrieveFile(remotePath+"/"+fileName,outputStream);
                    result = true;
                }
            }
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }
}

outputStream后面可以放在response中

 

2,在controller层编写代码实现下载功能:

package com.foxconn.dcc.controller;


import com.foxconn.dcc.utils.FtpUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;

/**
 * @author rookie
 * @date 2020/5/28 下午4:47
 * @description: 实现下载FTP文件功能
 * @modifiedBy:
 */
@Controller
@RequestMapping("/api/common/v1")
public class CommonController {

    @GetMapping(value = "/file/download")
    public void getFile( HttpServletResponse response,HttpServletRequest request) throws IOException {
        //

//        String savePath=jsonObject.getString("downloadUrl");
//        String fileUniqueName=jsonObject.getString("fileUniqueName");
//        String originFileName=jsonObject.getString("originFileName");
        System.out.println("进来了下载");
        String savePath="/rookie/dccFiles/202006";
        String fileUniqueName="4559e60e-cd54-411c-bed7-8042a82f52a9.pdf";
        String originFileName="原来.pdf";

        CommonUtil commonUtil=new CommonUtil();
        try {
            //解决下载文件时 中文文件名乱码问题
            boolean browserFlag = commonUtil.isMSBrowser(request);
            if (browserFlag) {
                //IE浏览器的乱码问题解决
                originFileName = URLEncoder.encode(originFileName, "UTF-8");
            } else {
                //万能乱码问题解决
                originFileName = new String(originFileName.getBytes("UTF-8"), "ISO-8859-1");
            }

            OutputStream os = new BufferedOutputStream(response.getOutputStream());
//            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment;fileName=" + originFileName);
            FtpUtil.downloadFile(savePath, fileUniqueName, os);
            os.flush();
            os.close();
        }catch (Exception e){

        }

    }
}

注意:返回参数为void,要不会报IllegalStateException的错误,即便是catch了,也是会报此错误

你可能感兴趣的:(java,spring)