10-21Spring Boot 整合 FastDFS 客戶端
一、前言
前兩篇整體上介紹了通過 Nginx 和 FastDFS 的整合來實現檔案伺服器。但是,在實際開發中對圖片或檔案的操作都是通過應用程式來完成的,因此,本篇將介紹 Spring Boot 整合 FastDFS 客戶端來實現對圖片/檔案伺服器的訪問。
如果有不瞭解 FastDFS 的讀者可以先瀏覽《FastDFS 環境搭建》 和 ofollow,noindex" target="_blank">《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>
三、測試
本篇只測試檔案上傳和訪問的效果,演示圖如下:
整合成功~~