欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot使用hutool操作FTP的詳細(xì)過程

 更新時(shí)間:2024年09月25日 09:33:21   作者:濤哥是個(gè)大帥比  
在使用SpringBoot結(jié)合hutool操作FTP時(shí),遇到防火墻導(dǎo)致上傳文件大小為0kb的問題,通過設(shè)置FTP為被動(dòng)模式解決,本文詳細(xì)解析了FTP的主動(dòng)模式和被動(dòng)模式的工作原理、安全性及適用場景,幫助理解FTP的連接方式和解決網(wǎng)絡(luò)限制問題

項(xiàng)目場景:

<dependency>
	<groupId>commons-net</groupId>
	<artifactId>commons-net</artifactId>
	<version>3.9.0</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.15</version>
</dependency>

實(shí)現(xiàn)步驟:

1、引入依賴

<dependency>
	<groupId>commons-net</groupId>
	<artifactId>commons-net</artifactId>
	<version>3.9.0</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.15</version>
</dependency>

2、yml配置 

ftp:
  # 服務(wù)器地址
  host: 127.0.0.1
  # 端口號
  port: 21
  # 用戶名
  userName: test
  # 密碼
  password: test

3、Config配置類

 我這里用的是static修飾的變量,方便工具類調(diào)用。

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
 * ftp配置
 */
@Configuration
public class FtpConfig {
    /**
     * 服務(wù)器地址
     */
    private static String host;
    /**
     * 端口
     */
    private static Integer port;
    /**
     * 用戶名
     */
    private static String userName;
    /**
     * 密碼
     */
    private static String password;
    @Value("${ftp.host}")
    public void setHost(String host) {
        FtpConfig.host = host;
    }
    public static String getHost() {
        return host;
    }
    @Value("${ftp.port}")
    public void setPort(Integer port) {
        FtpConfig.port = port;
    }
    public static Integer getPort() {
        return port;
    }
    @Value("${ftp.userName}")
    public void setUserName(String userName) {
        FtpConfig.userName = userName;
    }
    public static String getUserName() {
        return userName;
    }
    @Value("${ftp.password}")
    public void setPassword(String password) {
        FtpConfig.password = password;
    }
    public static String getPassword() {
        return password;
    }
}

4、 FtpUtil工具類

import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.ftp.Ftp;
import cn.hutool.extra.ftp.FtpMode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPFile;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
 * FTP服務(wù)工具類
 */
@Slf4j
public class FtpUtil {
    /**
     * 獲取 FTPClient對象
     */
    private static Ftp getFTPClient() {
        try {
            if(StringUtils.isBlank(FtpConfig.getHost()) || FtpConfig.getPort() == null
                || StringUtils.isBlank(FtpConfig.getUserName()) || StringUtils.isBlank(FtpConfig.getPassword())) {
                throw new RuntimeException("ftp配置信息不能為空");
            }
            Ftp ftp = new Ftp(FtpConfig.getHost(),FtpConfig.getPort(),FtpConfig.getUserName(),FtpConfig.getPassword());
            //設(shè)置為被動(dòng)模式,防止防火墻攔截
            ftp.setMode(FtpMode.Passive);
            return ftp;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("獲取ftp客戶端異常",e);
            throw new RuntimeException("獲取ftp客戶端異常:"+e.getMessage());
        }
    }
    /**
     * 下載ftp服務(wù)器上的文件到本地
     * @param remoteFile    ftp上的文件路徑
     * @param localFile     輸出的目錄,使用服務(wù)端的文件名
     */
    public static void download(String remoteFile, String localPath) {
        if(StringUtils.isBlank(remoteFile) || StringUtils.isBlank(localPath)) {
            return;
        }
        Ftp ftp = getFTPClient();
        try {
            if(!FileUtil.exist(localPath)){
                FileUtil.mkdir(localPath);
            }    
            File lFile = FileUtil.file(localPath);
            ftp.download(remoteFile, lFile);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("FTP文件下載異常",e);
        } finally {
            //關(guān)閉連接
            try {
                if(ftp != null)  ftp.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 本地文件上傳到ftp服務(wù)器上
     * @param remoteDir 上傳的ftp目錄
     * @param remoteFileName  保存到ftp服務(wù)器上的名稱
     * @param localFile 本地文件全名稱
     */
    public static boolean upload(String remoteDir, String remoteFileName, String localFile) {
        if(StringUtils.isBlank(remoteDir) || StringUtils.isBlank(remoteFileName) || StringUtils.isBlank(localFile)) {
            return false;
        }
        Ftp ftp = getFTPClient();
        try {
            File lFile = FileUtil.file(localFile);
            if(!lFile.exists()) {
                log.error("本地文件不存在");
                return false;
            }
            if(StringUtils.isBlank(remoteFileName)) {
                return ftp.upload(remoteDir, lFile);
            } else {
                return ftp.upload(remoteDir, remoteFileName, lFile);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("文件上傳FTP異常",e);
            return false;
        } finally {
            //關(guān)閉連接
            try {
                if(ftp != null)  ftp.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 刪除FTP服務(wù)器中的文件
     * @param remoteFile    ftp上的文件路徑
     */
    public static boolean delFile(String remoteFile) {
        if(StringUtils.isBlank(remoteFile)) {
            return false;
        }
        Ftp ftp = getFTPClient();
        try {
            return ftp.delFile(remoteFile);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("刪除FTP服務(wù)器中的文件異常",e);
            return false;
        } finally {
            //關(guān)閉連接
            try {
                if(ftp != null)  ftp.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 遍歷某個(gè)目錄下所有文件,不會(huì)遞歸遍歷
     * @param path    目錄
     */
    public static List<String> listFile(String path) {
        List<String> listFile = new ArrayList<>();
        Ftp ftp = getFTPClient();
        try {
            FTPFile[] ftpFiles = ftp.lsFiles(path);
            for (int i = 0; i < ftpFiles.length; i++) {
                FTPFile ftpFile = ftpFiles[i];
                if(ftpFile.isFile()){
                    listFile.add(ftpFile.getName());
                }
            }
            return listFile;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("遍歷某個(gè)目錄下所有文件異常",e);
            return null;
        } finally {
            //關(guān)閉連接
            try {
                if(ftp != null)  ftp.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

5、測試 

@RestController
@RequestMapping("/test")
public class TestController {
	@RequestMapping(value = "ftpTest", method = RequestMethod.GET)
	public void ftpTest() {
		//上傳文件到ftp
		FtpUtil.upload("opt/upload","APP_RELATION.sql", "F:/APP_RELATION.sql");
		//下載遠(yuǎn)程文件
		FtpUtil.download("opt/upload/APP_RELATION.sql", "D:/");
		//刪除遠(yuǎn)程文件
		FtpUtil.delFile("opt/upload/APP_RELATION.sql");
	}
}

總結(jié):

上傳的時(shí)候碰到一個(gè)問題,就是本地開啟防火墻時(shí),上傳的文件大小是0kb,必須要關(guān)了防火墻才正常,后來FTP模式設(shè)置為“被動(dòng)模式”解決。

//設(shè)置為被動(dòng)模式,防止防火墻攔截
ftp.setMode(FtpMode.Passive);

主動(dòng)模式(Active Mode):

  • 工作原理:客戶端在本地打開一個(gè)非特權(quán)端口(通常大于1023),并通過這個(gè)端口發(fā)送PORT命令給服務(wù)器,告訴服務(wù)器客戶端用于數(shù)據(jù)傳輸?shù)亩丝谔?。然后,服?wù)器使用其20端口(數(shù)據(jù)端口)主動(dòng)連接到客戶端指定的端口進(jìn)行數(shù)據(jù)傳輸。
  • 安全性:由于服務(wù)器需要主動(dòng)連接到客戶端的端口,這可能引發(fā)一些安全問題,特別是當(dāng)客戶端位于防火墻或NAT設(shè)備后面時(shí)。
  • 適用場景:適用于客戶端位于可以接受入站連接的網(wǎng)絡(luò)環(huán)境,且沒有防火墻或NAT設(shè)備限制的場景。

被動(dòng)模式(Passive Mode): 

  • 工作原理:客戶端發(fā)送PASV命令給服務(wù)器,服務(wù)器在本地打開一個(gè)端口(通常是高位的非特權(quán)端口),并通過PASV命令的響應(yīng)告訴客戶端這個(gè)端口號。然后,客戶端主動(dòng)連接到服務(wù)器指定的這個(gè)端口進(jìn)行數(shù)據(jù)傳輸。
  • 安全性:由于客戶端主動(dòng)連接到服務(wù)器,這種模式更適合于客戶端位于防火墻或NAT設(shè)備后面的場景,因?yàn)檫@些設(shè)備通常允許出站連接但限制入站連接。
  • 適用場景: 特別適用于網(wǎng)絡(luò)環(huán)境不穩(wěn)定、存在防火墻或NAT設(shè)備的場景。

到此這篇關(guān)于SpringBoot使用hutool操作FTP的文章就介紹到這了,更多相關(guān)SpringBoot使用hutool內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式

    SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式

    這篇文章主要介紹了SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • java web請求和響應(yīng)中出現(xiàn)中文亂碼問題的解析

    java web請求和響應(yīng)中出現(xiàn)中文亂碼問題的解析

    這篇文章主要為大家解析了java web請求和響應(yīng)中出現(xiàn)中文亂碼問題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java使用Apache compress實(shí)現(xiàn)文件夾壓縮成Zip包

    Java使用Apache compress實(shí)現(xiàn)文件夾壓縮成Zip包

    Apache common提供了很多實(shí)用的工具包,這篇文章主要來和大家介紹一下Java如何使用Apache compress包實(shí)現(xiàn)文件夾壓縮成Zip包,希望對大家有所幫助
    2024-01-01
  • SpringBoot整合Redis之編寫RedisConfig

    SpringBoot整合Redis之編寫RedisConfig

    RedisConfig需要對redis提供的兩個(gè)Template的序列化配置,所以本文為大家詳細(xì)介紹了SpringBoot整合Redis如何編寫RedisConfig,需要的可以參考下
    2022-06-06
  • SSH框架網(wǎng)上商城項(xiàng)目第6戰(zhàn)之基于DataGrid的數(shù)據(jù)顯示

    SSH框架網(wǎng)上商城項(xiàng)目第6戰(zhàn)之基于DataGrid的數(shù)據(jù)顯示

    SSH框架網(wǎng)上商城項(xiàng)目第6戰(zhàn)之基于DataGrid的數(shù)據(jù)顯示,提供了豐富的選擇、排序、分組和編輯數(shù)據(jù)的功能支持,感興趣的小伙伴們可以參考一下
    2016-05-05
  • SpringBoot 對象存儲(chǔ) MinIO的詳細(xì)過程

    SpringBoot 對象存儲(chǔ) MinIO的詳細(xì)過程

    MinIO 是一個(gè)基于 Go 實(shí)現(xiàn)的高性能、兼容 S3 協(xié)議的對象存儲(chǔ),它適合存儲(chǔ)海量的非結(jié)構(gòu)化的數(shù)據(jù),這篇文章主要介紹了SpringBoot 對象存儲(chǔ) MinIO,需要的朋友可以參考下
    2023-07-07
  • 關(guān)于Java中的 JSP 詳解

    關(guān)于Java中的 JSP 詳解

    JSP 代表 Java 服務(wù)器頁面。它是一種在應(yīng)用服務(wù)器端使用的編程工具。JSP 基本上用于支持平臺(tái)–獨(dú)立和動(dòng)態(tài)的方法來構(gòu)建 Web 依賴的應(yīng)用程序。JSP 頁面類似于 ASP 頁面,因?yàn)樗鼈兪窃诜?wù)器上編譯的,而不是在用戶的 Web 瀏覽器上進(jìn)行編譯。下面來看看文章的詳細(xì)介紹內(nèi)容
    2021-11-11
  • 淺談基于Token的WEB后臺(tái)認(rèn)證機(jī)制

    淺談基于Token的WEB后臺(tái)認(rèn)證機(jī)制

    這篇文章主要介紹了淺談基于Token的WEB后臺(tái)認(rèn)證機(jī)制,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • Java如何連接數(shù)據(jù)庫圖文教程

    Java如何連接數(shù)據(jù)庫圖文教程

    關(guān)于java數(shù)據(jù)庫的文章早已是非常多了,本文是對我個(gè)人過往學(xué)習(xí)java數(shù)據(jù)庫,理解及應(yīng)用java數(shù)據(jù)庫的一個(gè)總結(jié),下面這篇文章主要給大家介紹了關(guān)于Java如何連接數(shù)據(jù)庫的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Java項(xiàng)目中如何引入Hutool工具類并正確使用它

    Java項(xiàng)目中如何引入Hutool工具類并正確使用它

    Hutool是一個(gè)小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關(guān)API的學(xué)習(xí)成本,提高工作效率,使Java擁有函數(shù)式語言般的優(yōu)雅,這篇文章主要給大家介紹了關(guān)于Java項(xiàng)目中如何引入Hutool工具類并正確使用它的相關(guān)資料,需要的朋友可以參考下
    2024-01-01

最新評論