一、前言
前两篇介绍整体上介绍了通过 Nginx 和 FastDFS 的整合来实现文件服务器。但是,在实际开发中对图片或文件的操作都是通过应用程序来完成的,因此,本篇将介绍 Spring Boot 整合 FastDFS 客户端来实现对图片/文件服务器的访问。
如果有不了解 FastDFS 的读者可以先浏览 《FastDFS 环境搭建》 和 《Nginx 整合 FastDFS 实现文件服务器》 来普及内容,或是另行查阅网上相关资料。
二、整合编码
2.1 添加依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <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
1 2 3 4 5 6 7 8 9
| 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 后端代码
1 2 3 4 5 6 7
| @Configuration @Import(FdfsClientConfig.class) // 解决jmx重复注册bean的问题 @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING) public class ComponetImport { // 导入依赖组件 }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| @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()); } }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| @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 前端页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <!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>
|
三、测试
本篇只测试文件上传和访问的效果,演示图如下:
整合成功~~