原文地址:Spring Boot 整合 FastDFS 客戶端
博客地址:http://www.extlight.com
一、前言
前兩篇介紹整體上介紹了通過 Nginx 和 FastDFS 的整合來實現文件服務器。但是,在實際開發中對圖片或文件的操作都是通過應用程序來完成的,因此,本篇將介紹 Spring Boot 整合 FastDFS 客戶端來實現對圖片/文件服務器的訪問。
如果有不了解 FastDFS 的讀者可以先瀏覽《FastDFS 環境搭建》 和 《Nginx 整合 FastDFS 實現文件服務器》 來普及內容,或是另行查閱網上相關資料。
二、整合編碼
2.1 添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
上邊的 fastdfs-client 是並非 FastDFS Client 原作者編寫的整合包,具體詳情可以訪問 https://github.com/tobato/FastDFS_Client。
2.2 application.properties
server.port=8080
# fastDFS 配置
fdfs.so-timeout=1501
fdfs.connect-timeout=601
fdfs.thumb-image.width=150
fdfs.thumb-image.height=150
fdfs.web-server-url=192.168.10.110/
fdfs.tracker-list[0]=192.168.10.110:22122
2.3 后端代碼
- 加載 FastDFS 配置類:
@Configuration
@Import(FdfsClientConfig.class)
// 解決jmx重復注冊bean的問題
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class ComponetImport {
// 導入依賴組件
}
- FastDFS 工具類:
@Component
public class FastDFSClient {
private final Logger logger = LoggerFactory.getLogger(FastDFSClient.class);
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private FdfsWebServer fdfsWebServer;
/**
* 上傳文件
* @param file 文件對象
* @return 文件訪問地址
* @throws IOException
*/
public String uploadFile(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadFile(file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
return getResAccessUrl(storePath);
}
/**
* 上傳文件
* @param file 文件對象
* @return 文件訪問地址
* @throws IOException
*/
public String uploadFile(File file) throws IOException {
FileInputStream inputStream = new FileInputStream (file);
StorePath storePath = storageClient.uploadFile(inputStream,file.length(), FilenameUtils.getExtension(file.getName()),null);
return getResAccessUrl(storePath);
}
/**
* 將一段字符串生成一個文件上傳
* @param content 文件內容
* @param fileExtension
* @return
*/
public String uploadFile(String content, String fileExtension) {
byte[] buff = content.getBytes(Charset.forName("UTF-8"));
ByteArrayInputStream stream = new ByteArrayInputStream(buff);
StorePath storePath = storageClient.uploadFile(stream,buff.length, fileExtension,null);
return getResAccessUrl(storePath);
}
// 封裝圖片完整URL地址
private String getResAccessUrl(StorePath storePath) {
String fileUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
return fileUrl;
}
/**
* 下載文件
* @param fileUrl 文件url
* @return
*/
public byte[] download(String fileUrl) {
String group = fileUrl.substring(0, fileUrl.indexOf("/"));
String path = fileUrl.substring(fileUrl.indexOf("/") + 1);
byte[] bytes = storageClient.downloadFile(group, path, new DownloadByteArray());
return bytes;
}
/**
* 刪除文件
* @param fileUrl 文件訪問地址
* @return
*/
public void deleteFile(String fileUrl) {
if (StringUtils.isEmpty(fileUrl)) {
return;
}
try {
StorePath storePath = StorePath.praseFromUrl(fileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
} catch (FdfsUnsupportStorePathException e) {
logger.warn(e.getMessage());
}
}
}
- controller 類:
@RestController
@RequestMapping("/fdfs")
public class FastDFSController {
@Autowired
private FastDFSClient fdfsClient;
/**
* 文件上傳
* @param file
* @return
* @throws Exception
*/
@RequestMapping("/upload")
public Map<String,Object> upload(MultipartFile file) throws Exception{
String url = fdfsClient.uploadFile(file);
Map<String,Object> result = new HashMap<>();
result.put("code", 200);
result.put("msg", "上傳成功");
result.put("url", url);
return result;
}
/**
* 文件下載
* @param fileUrl url 開頭從組名開始
* @param response
* @throws Exception
*/
@RequestMapping("/download")
public void download(String fileUrl, HttpServletResponse response) throws Exception{
byte[] data = fdfsClient.download(fileUrl);
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("test.jpg", "UTF-8"));
// 寫出
ServletOutputStream outputStream = response.getOutputStream();
IOUtils.write(data, outputStream);
}
}
2.4 前端頁面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上傳</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
<style>
form {
margin-top: 30px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-sm-4"></div>
<div class="col-md-4 col-sm-4">
<h2> FastDFS 文件上傳</h2>
<form th:action="@{/fdfs/upload}" method="post" enctype="multipart/form-data">
<div class="form-group">
<input type="file" name="file" id="exampleInputFile">
</div>
<button type="submit" class="btn btn-default">上傳</button>
</form>
</div>
<div class="col-md-4 col-sm-4"></div>
</div>
</div>
</body>
</html>
三、測試
本篇只測試文件上傳和訪問的效果,演示圖如下:
整合成功~~