【FastDFS】SpringBoot整合FastDFS實戰,我只看這一篇!!


寫在前面

在《【FastDFS】小伙伴們說在CentOS 8服務器上搭建FastDFS環境總報錯?》和《【FastDFS】面試官:如何實現文件的大規模分布式存儲?(全程實戰)》文章中,我們詳細的搭建了FastDFS環境。那么,現在環境是有了,如何將FastDFS整合到項目中呢?今天,我們就一起來聊聊這個問題。

注:工程源碼已提交到:https://github.com/sunshinelyz/mykit-fastdfs

編譯Java客戶端

在FastDFS的官方Github上,專門有一個FastDFS Java客戶端的項目,鏈接地址為:https://github.com/happyfish100/fastdfs-client-java

我們將Java客戶端代碼下載的本地,然后進入項目的目錄,使用Maven進行編譯,如下所示。

git clone https://github.com/happyfish100/fastdfs-client-java.git
cd fastdfs-client-java
mvn clean install -Dmaven.test.skip=true 

接下來,我們需要將FastDFS的Java客戶端編譯安裝到本地的Maven倉庫。

mvn install:install-file -DgroupId=com.fastdfs -DartifactId=fastdfs-client-java -Dversion=1.29 -Dpackaging=jar -Dfile=fastdfs-client-java-1.29-SNAPSHOT.jar

到此,我們就在本地編譯安裝了FastDFS的Java客戶端。

搭建項目

編輯pom.xml文件

我們在IDEA中創建一個Maven項目,並在pom.xml文件中引入SpringBoot相關依賴和我們自己編譯的FastDFS的Java客戶端。最終,pom.xml文件的依賴如下所示。

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <skip_maven_deploy>false</skip_maven_deploy>
    <java.version>1.8</java.version>
    <logback.version>1.1.7</logback.version>
    <slf4j.version>1.7.21</slf4j.version>
    <common.logging>1.2</common.logging>
    <fastjson.version>1.2.51</fastjson.version>
    <fastdfs.client.version>1.29</fastdfs.client.version>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.6.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-undertow</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>${common.logging}</version>
    </dependency>

    <!-- log -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>${fastjson.version}</version>
    </dependency>

    <dependency>
        <groupId>com.fastdfs</groupId>
        <artifactId>fastdfs-client-java</artifactId>
        <version>${fastdfs.client.version}</version>
    </dependency>
</dependencies>

創建配置文件

(1)在項目的src/main/resources目錄下創建SpringBoot的配置文件application.yml,文件內容如下所示。

server:
  port: 9999
  servlet:
    context-path: /resource
  tomcat:
    uri-encoding: UTF-8
      
spring:
  servlet:
    multipart:
      max-file-size: 1024MB
      max-request-size: 1024MB
  main:
    allow-bean-definition-overriding: true
  profiles:
    include: test
    active: test
  output:
    ansi:
      enabled: detect

文件指定了項目啟動后監聽的端口,訪問的根路徑、項目編碼、文件上傳的大小,並指定了運行時的環境。

(2)在項目的src/main/resources目錄下創建logback-spring.xml日志文件,具體配置見源碼工程。

(3)在項目的src/main/resources目錄下創建fastdfs_client.conf文件,主要用來配置與FastDFS的連接信息。

connect_timeout = 200
network_timeout = 3000
charset = UTF-8
http.tracker_http_port = 8080
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
tracker_server = 192.168.175.100:22122

至此,項目搭建完成。接下來,我們就一起實現項目的功能。

項目開發

創建工具類

首先,我們在項目的io.mykit.fastdfs.utils包下創建FastDFSClientUtils工具類。這里,我給出工具類的核心實現,其他部分小伙伴們參加源碼工程。

/**
 * @author binghe
 * @description FastDFS分布式文件系統操作客戶端
 */
public class FastDFSClientUtils {

    private static Logger logger = LoggerFactory.getLogger(FastDFSClientUtils.class);

    private static TrackerClient trackerClient;

    public static void setFile(String filePath) {
        try {
            logger.info("初始化分布式文件系統服務開始...");
            if(filePath == null || filePath.trim().isEmpty()) {
                filePath = "fastdfs_client.conf";
            }
            ClientGlobal.init(filePath);
            TrackerGroup trackerGroup = ClientGlobal.g_tracker_group;
            trackerClient = new TrackerClient(trackerGroup);
            logger.info("初始化分布式文件系統服務完成...");
        } catch (Exception e) {
            logger.error("加載文件異常:{}",e );
        }
    }

    /**
     * @param data 數據
     * @param extName 文件擴展名
     * @return 上傳成功返回id,失敗返回null
     */
    public static String upload(byte[] data, String extName) {
        TrackerServer trackerServer = null;
        StorageServer storageServer = null;
        StorageClient1 storageClient1 = null;
        try {
            NameValuePair[] meta_list = null; // new NameValuePair[0];

            trackerServer = trackerClient.getTrackerServer();
            if (trackerServer == null) {
                logger.error("getConnection return null");
            }
            storageServer = trackerClient.getStoreStorage(trackerServer);
            storageClient1 = new StorageClient1(trackerServer, storageServer);
            String fileid = storageClient1.upload_file1(data, extName, meta_list);
            return fileid;
        } catch (Exception ex) {
            logger.error("上傳文件異常:{}", ex);
            return null;
        }finally{
            try {
                storageClient1.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            storageClient1 = null;
        }
    }

創建返回實體類

我們在io.mykit.fastdfs.bean包下創建ResourceBean類,用於SpringBoot接口返回結果數據,如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description 上傳圖片后的返回數據
 */
public class ResourceBean implements Serializable {
	private static final long serialVersionUID = -2788538880352897307L;
	
	/**
	 * 文件的訪問路徑
	 */
	private String fileUrl;
	
	/**
	 * 文件名稱
	 */
	private String fileName;
	
	public ResourceBean() {
		super();
	}

	public ResourceBean(String fileUrl, String fileName) {
		super();
		this.fileUrl = fileUrl;
		this.fileName = fileName;
	}

	public String getFileUrl() {
		return fileUrl;
	}

	public void setFileUrl(String fileUrl) {
		this.fileUrl = fileUrl;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	
}

其中,定義了文件的訪問路徑fileUrl和文件的名稱fileName。也就是說,文件上傳成功后,我們會向客戶端返回文件的訪問路徑和文件的名稱信息。

創建常量類

在io.mykit.fastdfs.constants包下創建ResourcesConstants常量類,ResourcesConstants類中主要定義了訪問文件的基礎路徑和獲取文件完整訪問路徑的方法,如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description 常量
 */
public class ResourcesConstants {
	private static final String BASE_RESOURCES_URL = "http://192.168.175.100/";
	public static String getResourcesUrl(String fileId) {
		return BASE_RESOURCES_URL.concat(fileId);
	}
}

創建Controller類

在項目的io.mykit.fastdfs.controller包下創建ResourceController類,用於定義文件上傳的接口。這個類的功能也比較簡單,就是定義一個文件上傳接口,接收文件,並調用FastDFSClientUtils工具類的upload(byte[], String)方法,將文件上傳到FastDFS中,如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description 上傳文件接口
 */
@RestController
@RequestMapping(value = "/resources/")
public class ResourceController {

	@RequestMapping(value={"/upload"}, method=RequestMethod.POST)
	@ResponseBody
	public ResourceBean upload(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response){
		String extName = "";
		String fileName = "";
		String originalFilename = file.getOriginalFilename();
		if(originalFilename.contains(".")) {
			//拆分文件路徑
			String[] fileArray = originalFilename.split("\\.");
			//獲取文件擴展名
			extName = fileArray[1];
			//獲取文件名
			fileName = fileArray[0];
		}else {
			fileName = originalFilename;
		}
		byte[] bytes = null;
		try {
			bytes = file.getBytes(); //將文件轉換成字節流形式
		} catch (IOException e) {
			e.printStackTrace();
		}
		//調用上傳文件的具體方法
		String fileId= FastDFSClientUtils.upload(bytes,extName);
		return new ResourceBean(ResourcesConstants.getResourcesUrl(fileId), fileName);
	} 
}

創建啟動類

在項目的io.mykit.fastdfs包下,創建項目啟動類ResourceStarter,如下所示。

/**
 * @author binghe
 * @version 1.0.0
 * @description 啟動
 */
@SpringBootApplication
public class ResourceStarter {
	public static void main(String[] args) {
		try {
			String filePath = "fastdfs_client.conf";
			if(args.length > 0) {
				filePath = args[0];
			}
			FastDFSClientUtils.setFile(filePath);
			SpringApplication.run(ResourceStarter.class, args);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

從代碼可以看出,ResourceStarter啟動類的main方法中,為filePath變量定義了一個默認的文件路徑為fastdfs_client.conf,當啟動項目時,為main()方法傳遞了參數,則會使用第一個參數覆蓋掉filePath默認的值,並調用FastDFSClientUtils類的setFile()方法將filePath傳遞到FastDFSClientUtils類中進行初始化操作。

創建html文件

最后,我們需要創建一個index.html文件,用於測試文件上傳操作。index.html文件的內容也比較簡單,如下所示。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"> 
	<title>文件上傳和下載</title>
</head>
<body>
<form action='http://192.168.175.100:9999/resource/resources/upload' method='post' enctype='multipart/form-data'>
	<input type='file' name='file'>
	<button type='submit'>上傳</button>
</form>
</body>
</html>

至此,我們整個項目就開發完成了。

項目測試

首先,我們在IDEA中將mykit-fastdfs項目打包成mykit-fastdfs.jar文件,然后將mykit-fastdfs.jar文件上傳到服務器的/usr/local/java目錄下,同時,我們將項目的src/main/resources目錄下的fastdfs_client.conf文件,復制一份到服務器的/usr/local/java目錄下。

在服務器命令行輸入如下命令啟動mykit-fastdfs.jar。

nohup java -jar /usr/local/java/mykit-fastdfs.jar /usr/local/java/fastdfs_client.conf >> /dev/null &

接下來,我們將index.html文件放到Nginx安裝目錄下的html/test目錄下。此時,在瀏覽器地址欄中輸入http://192.168.175.100/test/index.html就能夠打開頁面。

我們通過index.html頁面將文件上傳到FastDFS文件系統之后,瀏覽器中會顯示返回的結果數據,一個是文件的訪問路徑fileUrl,一個是文件的名稱fileName,如下所示。

{
    "fileUrl": "http://192.168.175.100/group1/M00/00/00/Ch8FQl9wfkSASTnYAACSPnJ7giA366.jpg",
    "fileName": "QQ截圖20200609234534"
}

具體如下圖所示。

我們打開fileUrl標識的文件訪問路徑,http://192.168.175.100/group1/M00/00/00/Ch8FQl9wfkSASTnYAACSPnJ7giA366.jpg,如下所示。


可以看到,瀏覽器能夠正確顯示上傳的圖片,說明我們已經在項目中成功整合了FastDFS的Java客戶端。

重磅福利

微信搜一搜【冰河技術】微信公眾號,關注這個有深度的程序員,每天閱讀超硬核技術干貨,公眾號內回復【PDF】有我准備的一線大廠面試資料和我原創的超硬核PDF技術文檔,以及我為大家精心准備的多套簡歷模板(不斷更新中),希望大家都能找到心儀的工作,學習是一條時而郁郁寡歡,時而開懷大笑的路,加油。如果你通過努力成功進入到了心儀的公司,一定不要懈怠放松,職場成長和新技術學習一樣,不進則退。如果有幸我們江湖再見!

另外,我開源的各個PDF,后續我都會持續更新和維護,感謝大家長期以來對冰河的支持!!

寫在最后

如果你覺得冰河寫的還不錯,請微信搜索並關注「 冰河技術 」微信公眾號,跟冰河學習高並發、分布式、微服務、大數據、互聯網和雲原生技術,「 冰河技術 」微信公眾號更新了大量技術專題,每一篇技術文章干貨滿滿!不少讀者已經通過閱讀「 冰河技術 」微信公眾號文章,吊打面試官,成功跳槽到大廠;也有不少讀者實現了技術上的飛躍,成為公司的技術骨干!如果你也想像他們一樣提升自己的能力,實現技術能力的飛躍,進大廠,升職加薪,那就關注「 冰河技術 」微信公眾號吧,每天更新超硬核技術干貨,讓你對如何提升技術能力不再迷茫!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM