上篇文章介绍了如何使用Spring Boot上传文件,这篇文章我们介绍如何使用Spring Boot将文件上传到分布式文件系统FastDFS中。

这个项目会在上一个项目的基础上进行构建。

1、pom包配置

我们使用Spring Boot最新版本1.5.9、jdk使用1.8、tomcat8.0。

  1. <dependency>
  2. <groupId>org.csource</groupId>
  3. <artifactId>fastdfs-client-java</artifactId>
  4. <version>1.27-SNAPSHOT</version>
  5. </dependency>

加入了fastdfs-client-java包,用来调用FastDFS相关的API。

2、配置文件

resources目录下添加fdfs_client.conf文件

  1. connect_timeout = 60
  2. network_timeout = 60
  3. charset = UTF-8
  4. http.tracker_http_port = 8080
  5. http.anti_steal_token = no
  6. http.secret_key = 123456
  7. tracker_server = 192.168.53.85:22122
  8. tracker_server = 192.168.53.86:22122

配置文件设置了连接的超时时间,编码格式以及tracker_server地址等信息

详细内容参考:fastdfs-client-java

3、封装FastDFS上传工具类

封装FastDFSFile,文件基础信息包括文件名、内容、文件类型、作者等。

  1. public class FastDFSFile {
  2. private String name;
  3. private byte[] content;
  4. private String ext;
  5. private String md5;
  6. private String author;
  7. //省略getter、setter

封装FastDFSClient类,包含常用的上传、下载、删除等方法。

首先在类加载的时候读取相应的配置信息,并进行初始化。

  1. static {
  2. try {
  3. String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();;
  4. ClientGlobal.init(filePath);
  5. trackerClient = new TrackerClient();
  6. trackerServer = trackerClient.getConnection();
  7. storageServer = trackerClient.getStoreStorage(trackerServer);
  8. } catch (Exception e) {
  9. logger.error("FastDFS Client Init Fail!",e);
  10. }
  11. }

文件上传

  1. public static String[] upload(FastDFSFile file) {
  2. logger.info("File Name: " + file.getName() + "File Length:" + file.getContent().length);
  3. NameValuePair[] meta_list = new NameValuePair[1];
  4. meta_list[0] = new NameValuePair("author", file.getAuthor());
  5. long startTime = System.currentTimeMillis();
  6. String[] uploadResults = null;
  7. try {
  8. storageClient = new StorageClient(trackerServer, storageServer);
  9. uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
  10. } catch (IOException e) {
  11. logger.error("IO Exception when uploadind the file:" + file.getName(), e);
  12. } catch (Exception e) {
  13. logger.error("Non IO Exception when uploadind the file:" + file.getName(), e);
  14. }
  15. logger.info("upload_file time used:" + (System.currentTimeMillis() - startTime) + " ms");
  16. if (uploadResults == null) {
  17. logger.error("upload file fail, error code:" + storageClient.getErrorCode());
  18. }
  19. String groupName = uploadResults[0];
  20. String remoteFileName = uploadResults[1];
  21. logger.info("upload file successfully!!!" + "group_name:" + groupName + ", remoteFileName:" + " " + remoteFileName);
  22. return uploadResults;
  23. }

使用FastDFS提供的客户端storageClient来进行文件上传,最后将上传结果返回。

根据groupName和文件名获取文件信息。

  1. public static FileInfo getFile(String groupName, String remoteFileName) {
  2. try {
  3. storageClient = new StorageClient(trackerServer, storageServer);
  4. return storageClient.get_file_info(groupName, remoteFileName);
  5. } catch (IOException e) {
  6. logger.error("IO Exception: Get File from Fast DFS failed", e);
  7. } catch (Exception e) {
  8. logger.error("Non IO Exception: Get File from Fast DFS failed", e);
  9. }
  10. return null;
  11. }

下载文件

  1. public static InputStream downFile(String groupName, String remoteFileName) {
  2. try {
  3. storageClient = new StorageClient(trackerServer, storageServer);
  4. byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
  5. InputStream ins = new ByteArrayInputStream(fileByte);
  6. return ins;
  7. } catch (IOException e) {
  8. logger.error("IO Exception: Get File from Fast DFS failed", e);
  9. } catch (Exception e) {
  10. logger.error("Non IO Exception: Get File from Fast DFS failed", e);
  11. }
  12. return null;
  13. }

删除文件

  1. public static void deleteFile(String groupName, String remoteFileName)
  2. throws Exception {
  3. storageClient = new StorageClient(trackerServer, storageServer);
  4. int i = storageClient.delete_file(groupName, remoteFileName);
  5. logger.info("delete file successfully!!!" + i);
  6. }

使用FastDFS时,直接调用FastDFSClient对应的方法即可。

4、编写上传控制类

从MultipartFile中读取文件信息,然后使用FastDFSClient将文件上传到FastDFS集群中。

  1. public String saveFile(MultipartFile multipartFile) throws IOException {
  2. String[] fileAbsolutePath={};
  3. String fileName=multipartFile.getOriginalFilename();
  4. String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
  5. byte[] file_buff = null;
  6. InputStream inputStream=multipartFile.getInputStream();
  7. if(inputStream!=null){
  8. int len1 = inputStream.available();
  9. file_buff = new byte[len1];
  10. inputStream.read(file_buff);
  11. }
  12. inputStream.close();
  13. FastDFSFile file = new FastDFSFile(fileName, file_buff, ext);
  14. try {
  15. fileAbsolutePath = FastDFSClient.upload(file); //upload to fastdfs
  16. } catch (Exception e) {
  17. logger.error("upload file Exception!",e);
  18. }
  19. if (fileAbsolutePath==null) {
  20. logger.error("upload file failed,please upload again!");
  21. }
  22. String path=FastDFSClient.getTrackerUrl()+fileAbsolutePath[0]+ "/"+fileAbsolutePath[1];
  23. return path;
  24. }

请求控制,调用上面方法saveFile()

  1. @PostMapping("/upload") //new annotation since 4.3
  2. public String singleFileUpload(@RequestParam("file") MultipartFile file,
  3. RedirectAttributes redirectAttributes) {
  4. if (file.isEmpty()) {
  5. redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
  6. return "redirect:uploadStatus";
  7. }
  8. try {
  9. // Get the file and save it somewhere
  10. String path=saveFile(file);
  11. redirectAttributes.addFlashAttribute("message",
  12. "You successfully uploaded '" + file.getOriginalFilename() + "'");
  13. redirectAttributes.addFlashAttribute("path",
  14. "file path url '" + path + "'");
  15. } catch (Exception e) {
  16. logger.error("upload file failed",e);
  17. }
  18. return "redirect:/uploadStatus";
  19. }

上传成功之后,将文件的路径展示到页面,效果图如下:

Spring Boot 使用 FastDFS - 图1

在浏览器中访问此Url,可以看到成功通过FastDFS展示:

Spring Boot 使用 FastDFS - 图2

这样使用Spring Boot 集成FastDFS的案例就完成了。