SpringBoot整合FTP文件服務器--圖片上傳到FTP圖片服務器

一,FTP文件服務器
 FTP 服務器就是支持 FTP 協議的服務器。我們可以在電腦中安裝FTP工具負責將電腦中的數據傳輸到服務器當中,這是服務器就稱爲FTP服務器,而我們的電腦稱爲客戶端。對於FTP服務器,用戶可通過FTP軟件和服務器建立連接,進行文件上傳、刪除、修改權限等操作。FTP 服務器一般分爲兩類:Windows FTP服務器和 Linux FTP 服務器。
二,SpringBoot 集成 FTP文件服務器
1.maven依賴

<!--ftp文件上傳-->
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.3</version>
        </dependency>

2.application.properties 配置文件 配置

#ftp use
ftp.server=39.97.98.252
ftp.port=65501
ftp.userName=hopsonftp
ftp.userPassword=hopsonSGgs12344321
ftp.bastPath=/hopson
ftp.imageBaseUrl=http://39.97.98.252:11018/hopson/image/
ftp.removeUrl=/hopson/image

3.創建 FTP文件服務器 工具類(使用時先在使用的地方注入==> @Autowired ==> private FtpUtil ftpUtil;)

/**
 * @program: hopson
 * @Date: 2019/8/4 11:23
 * @Author: wangmx
 * 
 * @Description:
 */
@Component
public class FtpUtil {

    Logger logger = LoggerFactory.getLogger(getClass());
    private String LOCAL_CHARSET = "GBK";

    //ftp服務器地址
    @Value("${ftp.server}")
    private String hostname;

    //ftp服務器端口
    @Value("${ftp.port}")
    private int port;

    //ftp登錄賬號
    @Value("${ftp.userName}")
    private String username;

    //ftp登錄密碼
    @Value("${ftp.userPassword}")
    private String password;

    //ftp保存目錄
    @Value("${ftp.bastPath}")
    private String basePath;


    /**
     * 初始化ftp服務器
     */
    public FTPClient getFtpClient() {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("utf-8");

        try {
            ftpClient.setDataTimeout(1000 * 120);//設置連接超時時間
            logger.info("connecting...ftp服務器:" + hostname + ":" + port);
            ftpClient.connect(hostname,port); // 連接ftp服務器
            ftpClient.login(username, password); // 登錄ftp服務器
            int replyCode = ftpClient.getReplyCode(); // 是否成功登錄服務器
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
                    "OPTS UTF8", "ON"))) {      // 開啓服務器對UTF-8的支持,如果服務器支持就用UTF-8編碼,否則就使用本地編碼(GBK).
                LOCAL_CHARSET = "UTF-8";
            }
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                logger.error("connect failed...ftp服務器:" + hostname + ":" + port);
            }
            logger.info("connect successfu...ftp服務器:" + hostname + ":" + port);
        } catch (MalformedURLException e) {
            logger.error(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return ftpClient;
    }


    /**
     * 上傳文件
     *
     * @param targetDir    ftp服務保存地址
     * @param fileName    上傳到ftp的文件名
     * @param inputStream 輸入文件流
     * @return
     */
    public boolean uploadFileToFtp(String targetDir, String fileName, InputStream inputStream) {
        boolean isSuccess = false;
        String servicePath = String.format("%s%s%s", basePath, "/", targetDir);
        FTPClient ftpClient = getFtpClient();
        try {
            if (ftpClient.isConnected()) {
                logger.info("開始上傳文件到FTP,文件名稱:" + fileName);
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//設置上傳文件類型爲二進制,否則將無法打開文件
                ftpClient.makeDirectory(servicePath);
                ftpClient.changeWorkingDirectory(servicePath);
                //設置爲被動模式(如上傳文件夾成功,不能上傳文件,註釋這行,否則報錯refused:connect  )
                ftpClient.enterLocalPassiveMode();//設置被動模式,文件傳輸端口設置
                ftpClient.storeFile(fileName, inputStream);
                inputStream.close();
                ftpClient.logout();
                isSuccess = true;
                logger.info(fileName + "文件上傳到FTP成功");
            } else {
                logger.error("FTP連接建立失敗");
            }
        } catch (Exception e) {
            logger.error(fileName + "文件上傳到FTP出現異常");
            logger.error(e.getMessage(), e);
        } finally {
            closeFtpClient(ftpClient);
            closeStream(inputStream);
        }
        return isSuccess;
    }

    public void closeStream(Closeable closeable) {
        if (null != closeable) {
            try {
                closeable.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    //改變目錄路徑
    public boolean changeWorkingDirectory(FTPClient ftpClient, String directory) {
        boolean flag = true;
        try {
            flag = ftpClient.changeWorkingDirectory(directory);
            if (flag) {
                logger.info("進入文件夾" + directory + " 成功!");

            } else {
                logger.info("進入文件夾" + directory + " 失敗!開始創建文件夾");
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return flag;
    }

    //創建多層目錄文件,如果有ftp服務器已存在該文件,則不創建,如果無,則創建
    public boolean CreateDirecroty(FTPClient ftpClient, String remote) throws IOException {
        boolean success = true;

        String directory = remote;
        if (!remote.endsWith(File.separator)) {
            directory = directory + File.separator;
        }
        // 如果遠程目錄不存在,則遞歸創建遠程服務器目錄
        if (!directory.equalsIgnoreCase(File.separator) && !changeWorkingDirectory(ftpClient, new String(directory))) {
            int start = 0;
            int end = 0;
            if (directory.startsWith(File.separator)) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf(File.separator, start);
            String path = "";
            String paths = "";
            while (true) {
                String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
                path = path + File.separator + subDirectory;
                if (!existFile(ftpClient, path)) {
                    if (makeDirectory(ftpClient, subDirectory)) {
                        changeWorkingDirectory(ftpClient, subDirectory);
                    } else {
                        logger.error("創建目錄[" + subDirectory + "]失敗");
                        changeWorkingDirectory(ftpClient, subDirectory);
                    }
                } else {
                    changeWorkingDirectory(ftpClient, subDirectory);
                }

                paths = paths + File.separator + subDirectory;
                start = end + 1;
                end = directory.indexOf(File.separator, start);
                // 檢查所有目錄是否創建完畢
                if (end <= start) {
                    break;
                }
            }
        }
        return success;
    }

    //判斷ftp服務器文件是否存在
    public boolean existFile(FTPClient ftpClient, String path) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpClient.listFiles(path);
        if (ftpFileArr.length > 0) {
            flag = true;
        }
        return flag;
    }

    //創建目錄
    public boolean makeDirectory(FTPClient ftpClient, String dir) {
        boolean flag = true;
        try {
            flag = ftpClient.makeDirectory(dir);
            if (flag) {
                logger.info("創建文件夾" + dir + " 成功!");

            } else {
                logger.info("創建文件夾" + dir + " 失敗!");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return flag;
    }

    /**
     * 下載文件 *
     *
     * @param pathName FTP服務器文件目錄 *
     * @param pathName 下載文件的條件*
     * @return
     */
    public boolean downloadFile(FTPClient ftpClient, String pathName, String targetFileName, String localPath) {
        boolean flag = false;
        OutputStream os = null;
        try {
            System.out.println("開始下載文件");
            //切換FTP目錄
            ftpClient.changeWorkingDirectory(pathName);
            ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                String ftpFileName = file.getName();
                if (targetFileName.equalsIgnoreCase(ftpFileName.substring(0, ftpFileName.indexOf(".")))) {
                    File localFile = new File(localPath);
                    os = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(file.getName(), os);
                    os.close();
                }
            }
            ftpClient.logout();
            flag = true;
            logger.info("下載文件成功");
        } catch (Exception e) {
            logger.error("下載文件失敗");
            logger.error(e.getMessage(), e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return flag;
    }

    /*下載文件*/
    public InputStream download(String ftpFile, FTPClient ftpClient) throws IOException {
        String servicePath = String.format("%s%s%s", basePath, "/", ftpFile);
        logger.info("【從文件服務器獲取文件流】ftpFile : " + ftpFile);
        if (StringUtils.isBlank(servicePath)) {
            throw new RuntimeException("【參數ftpFile爲空】");
        }
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        ftpClient.enterLocalPassiveMode();
        ftpFile = new String(servicePath.getBytes("utf-8"), "iso-8859-1");
        return ftpClient.retrieveFileStream(ftpFile);
    }

    /**
     * 刪除文件 *
     *
     * @param pathname FTP服務器保存目錄 *
     * @param filename 要刪除的文件名稱 *
     * @return
     */
    public boolean deleteFile(String pathname, String filename) {
        boolean flag = false;
        FTPClient ftpClient = getFtpClient();
        try {
            logger.info("開始刪除文件");
            if (ftpClient.isConnected()) {
                //切換FTP目錄
                ftpClient.changeWorkingDirectory(pathname);
                ftpClient.enterLocalPassiveMode();
                ftpClient.dele(filename);
                ftpClient.logout();
                flag = true;
                logger.info("刪除文件成功");
            } else {
                logger.info("刪除文件失敗");

            }
        } catch (Exception e) {
            logger.error("刪除文件失敗");
            logger.error(e.getMessage(), e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return flag;
    }

    public void closeFtpClient(FTPClient ftpClient) {
        if (ftpClient.isConnected()) {
            try {
                ftpClient.disconnect();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    public InputStream downloadFile(FTPClient ftpClient, String pathname, String filename) {
        InputStream inputStream = null;
        try {
            System.out.println("開始下載文件");
            //切換FTP目錄
            ftpClient.changeWorkingDirectory(pathname);
            ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                if (filename.equalsIgnoreCase(file.getName())) {
                    inputStream = ftpClient.retrieveFileStream(file.getName());
                    break;
                }
            }
            ftpClient.logout();
            logger.info("下載文件成功");
        } catch (Exception e) {
            logger.error("下載文件失敗");
            logger.error(e.getMessage(), e);
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return inputStream;
    }
}

4.Controller 案例代碼

@RequestMapping(value = "/add/photo",method = RequestMethod.POST)
    public R upload(MultipartFile file){
        String s = dkPhotoService.updatePhoto(file);
        return R.ok();
    }

5.service 層代碼

//圖片上傳
String updatePhoto(MultipartFile file);

6.serviceImpl 案例層代碼

/**
     * 圖片上傳
     * @param file
     * @return
     */
    @Override
    public String updatePhoto(MultipartFile file) {
    	//給圖片起一個新的名稱,防止在圖片名稱重複
        String newname=new String();
        
        if(file!=null){
        	//生成新的圖片名稱
            newname = System.currentTimeMillis()+file.getOriginalFilename();
            try {
            	//圖片上傳,調用ftp工具類 image 上傳的文件夾名稱,newname 圖片名稱,inputStream
                boolean hopson = ftpUtil.uploadFileToFtp("image", newname, file.getInputStream());
                if(hopson) {
                	// 把圖片信息存入到數據庫中
                    DkPhoto dkPhoto = new DkPhoto();
                    dkPhoto.setName(newname);
                    dkPhoto.setMassifId(massifId);
                    dkPhoto.setPhoto(path + newname);
                    this.insert(dkPhoto);
                }
            } catch (Exception e) {
                e.printStackTrace();
                return "error";
            }
        }
        return "sucess";
    }

三,出現上傳失敗
先檢查配置 是否正確,如果出現 java.net.SocketException 說明連接不上 FTP 文件服務器 請檢查 文件服務器地址 和 用戶名 以及密碼,以及 FTP 文件服務器是否搭建正確

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章