程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

系列学习分布式文件系统 FastDFS 之第 4 篇 —— SpringBoot 整合操作 FastDFS 实现上传文件(完结)

发布于2021-06-12 13:23     阅读(125)     评论(0)     点赞(17)     收藏(2)


查看之前的博客可以点击顶部的【分类专栏】

在前面的博客已经搭建好了 FastDFS,这篇博客讲解如何使用 SpringBoot 整合 FastDFS。

 

本案例代码地址:https://pan.baidu.com/s/1xks-4auLI8ubjniRGGZB7g  提取码:fapa

 

只粘贴重要代码,其余代码看源码地址!

1、pom.xml 依赖。FastDFS 我们使用 com.github.tobato 封装好的 fastdfs-client,同时必须加上 commons-fileupload 依赖,否则报错:ClassNotFoundException DiskFileItemFactory

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.study</groupId>
  7. <artifactId>study-fastdfs</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <parent>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-parent</artifactId>
  12. <version>2.2.2.RELEASE</version>
  13. </parent>
  14. <!-- 统一配置版本 -->
  15. <properties>
  16. <fastdfs.version>1.27.2</fastdfs.version>
  17. <commons-fileupload.version>1.4</commons-fileupload.version>
  18. <fastjson.version>1.2.75</fastjson.version>
  19. </properties>
  20. <dependencies>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-web</artifactId>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-test</artifactId>
  28. <scope>test</scope>
  29. </dependency>
  30. <!-- fastdfs 依赖:https://mvnrepository.com/artifact/com.github.tobato/fastdfs-client -->
  31. <dependency>
  32. <groupId>com.github.tobato</groupId>
  33. <artifactId>fastdfs-client</artifactId>
  34. <version>${fastdfs.version}</version>
  35. </dependency>
  36. <!-- 要加上 commons-fileupload,否则报错:ClassNotFoundException DiskFileItemFactory-->
  37. <dependency>
  38. <groupId>commons-fileupload</groupId>
  39. <artifactId>commons-fileupload</artifactId>
  40. <version>${commons-fileupload.version}</version>
  41. </dependency>
  42. <!-- lombok 依赖 -->
  43. <dependency>
  44. <groupId>org.projectlombok</groupId>
  45. <artifactId>lombok</artifactId>
  46. </dependency>
  47. <!-- 阿里巴巴 fastjson -->
  48. <dependency>
  49. <groupId>com.alibaba</groupId>
  50. <artifactId>fastjson</artifactId>
  51. <version>${fastjson.version}</version>
  52. </dependency>
  53. </dependencies>
  54. </project>

 

2、controller 层

  1. package com.study.controller;
  2. import com.alibaba.fastjson.JSON;
  3. import com.study.message.ResponseMsg;
  4. import com.study.service.FileService;
  5. import com.study.util.NetworkUtil;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import javax.servlet.http.HttpServletRequest;
  10. import java.net.URL;
  11. /**
  12. * @author biandan
  13. * @description 文件上传
  14. * @signature 让天下没有难写的代码
  15. * @create 2021-06-09 上午 12:07
  16. */
  17. @RestController
  18. @RequestMapping("/file")
  19. public class FastDFSController {
  20. @Autowired
  21. private FileService fileService;
  22. /**
  23. * 文件上传
  24. *
  25. * @param request
  26. * @return
  27. */
  28. @RequestMapping("/upload")
  29. public ResponseMsg upload(HttpServletRequest request) {
  30. //单纯的获取一些信息,与业务逻辑无关。如果想要这些信息搞事情,也是可以的
  31. try {
  32. String referer = request.getHeader("Referer");
  33. System.out.println("referer=" + referer);
  34. String ipAddress = NetworkUtil.getIpAddress(request);
  35. System.out.println("ipAddress=" + ipAddress);
  36. URL url = new URL(referer);
  37. String host = url.getHost();
  38. System.out.println("host=" + host);
  39. } catch (Exception e) {
  40. e.printStackTrace();
  41. }
  42. Long startTime = System.currentTimeMillis();//记录开始时间
  43. ResponseMsg responseMsg = fileService.upload(request);
  44. Long endTime = System.currentTimeMillis();//记录结束时间
  45. System.out.println("上传文件共花费时间:" + ((endTime - startTime) / 1000) + " 秒");
  46. System.out.println("responseMsg=" + JSON.toJSONString(responseMsg));
  47. return responseMsg;
  48. }
  49. }

 

3、实现类

  1. package com.study.service.impl;
  2. import com.alibaba.fastjson.JSON;
  3. import com.github.tobato.fastdfs.domain.fdfs.StorePath;
  4. import com.github.tobato.fastdfs.service.FastFileStorageClient;
  5. import com.study.entity.FileResponseEntity;
  6. import com.study.message.ResponseMsg;
  7. import com.study.service.FileService;
  8. import org.apache.commons.lang3.StringUtils;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.beans.factory.annotation.Value;
  11. import org.springframework.stereotype.Service;
  12. import org.springframework.util.CollectionUtils;
  13. import org.springframework.web.multipart.MultipartFile;
  14. import org.springframework.web.multipart.MultipartHttpServletRequest;
  15. import org.springframework.web.multipart.commons.CommonsMultipartResolver;
  16. import javax.servlet.http.HttpServletRequest;
  17. import java.util.ArrayList;
  18. import java.util.Iterator;
  19. import java.util.List;
  20. /**
  21. * @author biandan
  22. * @description
  23. * @signature 让天下没有难写的代码
  24. * @create 2021-06-09 上午 12:17
  25. */
  26. @Service
  27. public class FileServiceImpl implements FileService {
  28. //FastDFS 客户端
  29. @Autowired(required = false)
  30. private FastFileStorageClient fastFileStorageClient;
  31. //使用的组,这里默认是 group1
  32. @Value("${fastdfs.group:group1}")
  33. private String group;
  34. //访问的域名
  35. @Value("${fastdfs.domain}")
  36. private String domain;
  37. /**
  38. * 上传文件
  39. *
  40. * @param request
  41. * @return
  42. */
  43. @Override
  44. public ResponseMsg upload(HttpServletRequest request) {
  45. ResponseMsg responseMsg = new ResponseMsg();
  46. responseMsg.setCode("-1");
  47. responseMsg.setMessage("upload file error!");
  48. try {
  49. List<FileResponseEntity> list = dealWithFile(request);
  50. if (!CollectionUtils.isEmpty(list)) {
  51. responseMsg.setData(list);
  52. responseMsg.setCode("0");
  53. responseMsg.setMessage("success");
  54. }
  55. } catch (Exception e) {
  56. e.printStackTrace();
  57. }
  58. return responseMsg;
  59. }
  60. /**
  61. * 处理文件
  62. *
  63. * @param request
  64. * @return
  65. */
  66. private List<FileResponseEntity> dealWithFile(HttpServletRequest request) throws Exception {
  67. List<FileResponseEntity> list = new ArrayList<>();
  68. //将上下文的请求给 CommonsMultipartResolver (多部分解析器)
  69. CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
  70. //判断 form 表单中是否有多文件 enctype="multipart/form-data"
  71. if (multipartResolver.isMultipart(request)) {
  72. //将请求 request 变成多部分 request
  73. MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
  74. //获取 multipartRequest 所有文件名
  75. Iterator iterator = multipartRequest.getFileNames();
  76. while (iterator.hasNext()) {
  77. //一次性遍历所有文件
  78. MultipartFile file = multipartRequest.getFile(iterator.next().toString());
  79. if (null != file && !file.isEmpty()) {
  80. FileResponseEntity responseEntity = new FileResponseEntity();
  81. //使用 FastDFS 客户端上传文件
  82. StorePath storePath = fastFileStorageClient.uploadFile(group, file.getInputStream(), file.getSize(), getFileExt(file.getOriginalFilename()));
  83. System.out.println("storePath=" + JSON.toJSONString(storePath));
  84. responseEntity.setOriginalName(file.getOriginalFilename());
  85. //拼接完整路径
  86. String fullPath = domain + storePath.getFullPath();
  87. responseEntity.setTargetName(StringUtils.right(fullPath, fullPath.length() - fullPath.lastIndexOf("/") - 1));
  88. responseEntity.setFullPath(fullPath);
  89. list.add(responseEntity);
  90. }
  91. }
  92. }
  93. return list;
  94. }
  95. /**
  96. * 获取文件扩展名
  97. *
  98. * @param fileName
  99. * @return
  100. */
  101. private String getFileExt(String fileName) {
  102. String extName = "";
  103. if (StringUtils.isNotBlank(fileName) && fileName.lastIndexOf(".") != -1) {
  104. extName = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
  105. }
  106. return extName;
  107. }
  108. }

4、解决 JMX 重复注册 Bean 的问题

  1. package com.study.config;
  2. import com.github.tobato.fastdfs.FdfsClientConfig;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.EnableMBeanExport;
  5. import org.springframework.context.annotation.Import;
  6. import org.springframework.jmx.support.RegistrationPolicy;
  7. /**
  8. * @author biandan
  9. * @description
  10. * @signature 让天下没有难写的代码
  11. * @create 2021-06-09 上午 1:14
  12. */
  13. @Configuration
  14. @Import(FdfsClientConfig.class)
  15. // 处理 JMX 重复注册 Bean 的问题
  16. @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
  17. public class FastDfsConfig {
  18. }

 

5、解决跨域请求问题

  1. package com.study.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.cors.CorsConfiguration;
  5. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  6. import org.springframework.web.filter.CorsFilter;
  7. /**
  8. * @author biandan
  9. * @description 解决跨域
  10. * @signature 让天下没有难写的代码
  11. * @create 2021-06-09 上午 11:08
  12. */
  13. @Configuration
  14. public class CrossConfiguration {
  15. @Bean
  16. public CorsFilter corsFilter() {
  17. final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  18. final CorsConfiguration config = new CorsConfiguration();
  19. config.setAllowCredentials(true); // 允许cookies跨域
  20. config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
  21. config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
  22. config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
  23. config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
  24. source.registerCorsConfiguration("/**", config);
  25. return new CorsFilter(source);
  26. }
  27. }

 

6、前端测试代码,需要引入 jquery.min.js  (直接从 IDEA 里使用浏览器打开即可进入测试页面!)

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <title>FastDFS分布式文件服务器</title>
  6. <script src="js/jquery.min.js"></script>
  7. <script type="text/javascript">
  8. var baseUrl = "http://127.0.0.1/";
  9. //文件上传接口
  10. function uploadFile() {
  11. var formData = new FormData();
  12. formData.append("file", $("#upload")[0].files[0]);
  13. var uploadPath = baseUrl + "file/upload/";
  14. $.ajax({
  15. url: uploadPath,
  16. type: 'POST',
  17. data: formData,
  18. xhrFields: {
  19. 'Access-Control-Allow-Origin': '*',
  20. withCredentials: true
  21. },
  22. contentType: false,
  23. processData: false,
  24. beforeSend: function () {
  25. console.log("正在上传,请稍候...");
  26. },
  27. success: function (data) {
  28. console.log("结果:" + JSON.stringify(data));
  29. $("#resultArea").val(JSON.stringify(data));
  30. if (data.code === '0') {
  31. $("#opResult").text("");
  32. $("#opResult").css("color", "blue");
  33. $("#opResult").text("操作成功!");
  34. } else {
  35. $("#opResult").text("");
  36. $("#opResult").css("color", "red");
  37. $("#opResult").text("操作失败!");
  38. }
  39. },
  40. error: function (data) {
  41. console.log("结果:" + JSON.stringify(data));
  42. $("#resultArea").val(JSON.stringify(data));
  43. if (data.code === '0') {
  44. $("#opResult").text("");
  45. $("#opResult").css("color", "blue");
  46. $("#opResult").text("操作成功!");
  47. } else {
  48. $("#opResult").text("");
  49. $("#opResult").css("color", "red");
  50. $("#opResult").text("操作失败!");
  51. }
  52. }
  53. });
  54. }
  55. </script>
  56. </head>
  57. <body style="width: 960px;margin:0px 150px;">
  58. <h1>FastDFS分布式文件上传</h1>
  59. <br>
  60. <div>
  61. <input id="upload" type="file" name="file" value="选择文件"/>
  62. <input id="materiel" type="hidden" name="materiel" value="">
  63. <button onclick="uploadFile()">上传文件</button>
  64. </div>
  65. <br><br>
  66. <span>结果:</span><span id="opResult"></span><br>
  67. <textarea id="resultArea" cols="120" rows="6"></textarea><br><br>
  68. </body>
  69. </html>

7、application.yml 配置

  1. server:
  2. port: 80
  3. # 将SpringBoot项目作为单实例部署调试时,不需要注册到注册中心
  4. eureka:
  5. client:
  6. fetch-registry: false
  7. register-with-eureka: false
  8. spring:
  9. application:
  10. name: fastdfs-server
  11. # servlet 相关配置
  12. # SpringBoot 1.5版本是spring.http.multipart
  13. # SpringBoot 2.0版本是spring.servlet.multipart
  14. servlet:
  15. multipart:
  16. max-file-size: 50MB # 最大文件限制大小,默认1M
  17. max-request-size: 50MB #最大请求大小,默认10M
  18. enabled: true
  19. # 分组的配置
  20. fastdfs:
  21. group: group1
  22. domain: http://file.study.com/
  23. # 分布式文件系统 FastDFS 配置
  24. fdfs:
  25. so-timeout: 100000 #读取时间
  26. connect-timeout: 100000 # 连接超时时间
  27. tracker-list: # tracker 服务配置列表
  28. - 192.168.0.105:22122
  29. # 连接池配置
  30. pool:
  31. #从连接池中借出的最大数目
  32. max-total: 1000
  33. #取连接时的最大等待毫秒数
  34. max-wait-millis: 600000

 

OK,启动测试。

后台输出

 

fullPath 就是访问的路径了:http://file.study.com/group1/M00/00/00/wKgAaWDAOFeAUMNAABO1_VdUnLo570.gif

 

OK,测试完成!

这里提供一下张家辉相关表情包制作地址:https://www.gifhome.com/diy/42.html   可以根据自己想要的信息输出 gif 图,网站首页还有多款斗图可以选,让你跟基友斗图不再孤独!!

 

博客代码地址:https://pan.baidu.com/s/1xks-4auLI8ubjniRGGZB7g  提取码:fapa

 

 

 

 

 

原文链接:https://blog.csdn.net/BiandanLoveyou/article/details/117714543



所属网站分类: 技术文章 > 博客

作者:niceboty

链接:http://www.javaheidong.com/blog/article/222110/d670172bab92c6335a84/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

17 0
收藏该文
已收藏

评论内容:(最多支持255个字符)