文章目錄
FastDFS文件系統Java客戶端是指採用Java語言編寫的一套程序,專門用來訪問fastDFS文件系統,其實就是一個jar包。
一、打包jar
由於maven中央倉庫沒有fastdfs-client-java的jar包,所以需要從官方下載FastDFS源代碼到本地,然後安裝到本地倉庫
下載地址,格式是.zip:https://codeload.github.com/happyfish100/fastdfs-client-java/zip/master
下載完畢後解壓,解壓完畢後可以看到是一個maven項目,可以直接採用maven命令編譯成jar安裝到本地maven庫
mvn clean install
也可以導入到IDEA中再進行安裝
這是我打好的包:https://download.csdn.net/download/zyx1260168395/12095175
二、上傳、下載與刪除實現
(1)添加依賴
在FastDFS源碼中,找到maven座標,添加到自己的項目中(已經安裝到本地倉庫)
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27-SNAPSHOT</version>
</dependency>
(2)配置
新建一個配置類,我起名爲fastdfs.conf,在該文件中指定跟蹤器的地址:
tracker_server=192.168.29.128:22122
(3)上傳
固定步驟:
-
加載(2)中建的配置文件
-
通過一系列固定步驟,獲取到Storage的客戶端對象
StorageClient
,通過該對象來操作FastDFS -
上傳常用的方法,方法2在web中常用:
String[] upload_appender_file(String local_filename, String file_ext_name, NameValuePair[] meta_list)
- 參數 1 爲需要上傳的文件在本地磁盤的絕對路徑
- 參數 2 爲需要上傳的文件的擴展名
- 參數 3 爲需要上傳的文件的屬性文件,通常爲null不上傳,這些文件的屬性例如文件大小以及類型等信息通常需要記錄到數據庫中
String[] upload_appender_file(byte[] file_buff, String file_ext_name, NameValuePair[] meta_list)
- 參數 1 爲需要上傳的文件的字節流
- 參數 2和3 同上
-
方法返回一個字符串數組,數組中的值表示了文件在FastDFS中存儲的位置
- 下標爲0的字符串:保存的是文件存儲的組名
- 下標爲1的字符串:保存的是文件在FastDFS中存儲的名字
-
關閉可以關閉的
public static void upload() {
TrackerServer ts = null;
StorageServer ss = null;
try {
//加載配置文件,目的是爲了獲取所有的TrackerServer的地址信息
ClientGlobal.init("fastdfs.conf");
TrackerClient tc = new TrackerClient();
ts = tc.getConnection();
ss = tc.getStoreStorage(ts);
//創建Storage的客戶端對象,需要利用這個對象來操作FastDFS,實現文件的上傳下載和刪除
StorageClient sc = new StorageClient(ts, ss);
//上傳文件到FastDFS
//參數 1 爲需要上傳的文件在本地磁盤的絕對路徑
//參數 2 爲需要上傳的文件的擴展名
//參數 3 爲需要上傳的文件的屬性文件通常爲null不上傳,這些文件的屬性例如文件大小以及類型等信息通常需要記錄到數據庫中
//返回一個字符串數組,這個數組中的數據非常重要必須要妥善保管
//注意:這個數組中的第一個元素爲文件所在的FastDFS的組名,第二個元素爲文件在FastDFS中的遠程文件名稱
// 這兩個數據通常我們是需要寫入到數據庫中的
String[] result = sc.upload_file("d:/qrcode.jpg", "jpg", null);
for (String str : result) {
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
} finally {
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ts != null) {
try {
ts.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
(4)下載與刪除
大部分步驟與上傳一樣,只是調用了Storage的客戶端對象StorageClient
的不同方法:
下載:
- 方法1:
int download_file(String group_name, String remote_filename, String local_filename)
- 參數 1:文件在FastDFS中的組名
- 參數 2:文件在FastDFS中的遠程文件名
- 參數 3:文件需要保存到本地磁盤的某個絕對路徑
- 返回值爲 int 類型的整數,0表示下載文件成功,不爲0表示不成功,具體的數字代表了不成功的原因
- 方法2,web中常用:
byte[] download_file(String group_name, String remote_filename)
- 參數 1:文件在FastDFS中的組名
- 參數 2:文件在FastDFS中的遠程文件名
- 返回值爲byte數組類型,表示文件的具體內容
刪除:
int delete_file(String group_name, String remote_filename)
- 參數 1 爲文件在FastDFS中的組名
- 參數 2 爲文件在FastDFS中的遠程文件名
- 返回值爲 int 類型的整數,0表示刪除成功
三、web中前端上傳與下載文件
需要添加依賴,同2.1,這裏就不細說了
1. 配置文件上傳大小
SpringBoot中設置SpringMVC上傳文件大小 的限制:
#如果需要修改SpringMVC上傳文件的限制那麼儘可能同時修改以下2個屬性
#設置SpringMVC允許上傳時的單個文件大小默認爲 1MB
spring.servlet.multipart.max-file-size=1MB
#設置SpringMVC每個請求允許上傳的文件總大小默認值爲 10MB
spring.servlet.multipart.max-request-size=10MB
2. 前端上傳文件
如果表單中擁有文件那麼
method
必須是post
enctype
必須是multipart/form-data
<form th:action="@{|/upload|}" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile"><br>
<input type="submit" value="上傳文件">
</form>
小技巧:使用隱藏的
<iframe>
實現同步請求模擬出ajax請求的效果,不刷新頁面
- 在頁面中加入<iframe name=“success” style=“display: none”></iframe>
- 在form表單中添加參數:target=“success”,指向<iframe>
- 後臺返回的頁面中有如下函數:
<script> if(confirm("[[${message}]]")){ window.top.location.href="當前頁面" } </script>
3. 後臺接收文件
後臺處理傳遞回來的文件,要在Controller層將文件存入FastDFS,原因有二:
- MultipartFile這個類來自於springframework.web包下的,是web組件,按照MVC的層次關係,MultipartFile只能在Controller層使用
- 如果要傳到Service層(Service可能是遠程服務器),需要把字節流也傳到Service層,過於耗費資源,不現實
後臺使用MultipartFile對象來接收前臺傳輸過來的文件,MultipartFile 是Spring提供的一個類,作用是用於封裝請求中的文件域中的數據。
MultipartFile對象的方法:
byte[] b = uploadFile.getBytes(); //獲取文件所對應的字節數組
String type = uploadFile.getContentType(); //獲取文件類型,例如:圖片類型:image/jpeg
InputStream in = uploadFile.getInputStream(); //獲取文件所對應的輸入流
String remoteName = uploadFile.getName(); //獲取文件域的name屬性(MultipartFile對象的名字),例如:uploadFile
String name = uploadFile.getOriginalFilename(); //獲取文件的名字,例如:aaa.jpg
long size = uploadFile.getSize(); //獲取文件大小
boolean b = uploadFile.isEmpty() //判斷文件是否爲空,沒有上傳文件或文件大小爲0,返回值爲true表示文件爲空
將接收的文件存入到FastDFS中:
@RequestMapping("/upload")
public String upload(MultipartFile uploadFile) throws IOException {
//獲取文件名字,並從文件名字中截取後綴名
String fileName = uploadFile.getOriginalFilename();
String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1);
//將文件上傳到FastDFS中(這裏只是將2.3中的第二個方法封裝成了工具類)
String result[] = FastDFSUtils.upload(uploadFile.getBytes(), fileExtName);
//後續處理,將返回的result[]中的String保存到數據庫中,供下載時使用
}
4. 前端下載文件
使用ResponseEntity來返回文件流,ResponseEntity 對象表示響應體,它是最終返回給瀏覽器的對象,我們可以通過設置ResponseEntity對象來改變最終返回瀏覽的數據內容
ResponseEntity與@ResponseBody的區別:
- @ResponseBody可以直接返回Json結果,
- ResponseEntity不僅可以返回json結果,還可以定義返回的HttpHeaders和HttpStatus
- ResponseEntity的優先級高於@ResponseBody。在不是ResponseEntity的情況下才去檢查有沒有@ResponseBody註解。如果響應類型是ResponseEntity可以不寫@ResponseBody註解,寫了也沒有關係。
注意:這裏我們泛型爲byte數組,表示本次響應時以字節數組的方式進行響應,瀏覽器會彈出一個下載窗口
@RequestMapping("/download")
public ResponseEntity<byte[]> download(String groupName, String remoteFilePath) {
//從FastDFS中獲取到要下載的文件,使用的是2.4下載中的方法2
byte[] buffFile = FastDFSUtils.download(groupName, remoteFilePath);
//創建Http的響應頭文件對象
HttpHeaders headers = new HttpHeaders();
//設置響應頭中的響應類型爲文件類型,這樣瀏覽纔會彈出下載窗口
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//設置被下載的文件的大小,否則瀏覽器不會顯示下載進度
headers.setContentLength(creditorInfo.getFileSize());
//指定文件下載時的默認文件名稱,第一個參數內容固定
headers.setContentDispositionFormData("attachment", creditorInfo.getOldFileName());
//創建一個ResponseEntity對象,構造方法的參數:
//第一個參數:響應的字節數組
//第二個參數:Http響應頭文件對象,設置響應的頭信息
//第三個參數:響應的狀態碼,是常量,HttpStatus.OK 表示 200
ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(buffFile, headers, HttpStatus.OK);
return responseEntity;
}
5. 刪除文件簡介
刪除FastDFS和清除數據庫,所以我們將這些業務都放在service中進行事務的處理
要先更新數據庫,如果更新成功,再刪除FastDFS中的文件