SpringBoot集成FastDFS依赖实现文件上传

前言

对FastDFS文件系统安装后的使用。

FastDFS的安装请参考这篇:https://www.cnblogs.com/niceyoo/p/13511082.html

本文环境:IDEA + JDK1.8 + Maven

1、引入依赖

简单说一下这个依赖部分,目前大部分都是采用的如下依赖:

<!-- https://mvnrepository.com/artifact/net.oschina.zcx7878/fastdfs-client-java -->
<dependency><groupId>net.oschina.zcx7878</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27.0.0</version>
</dependency>

本着不重复造轮子,且为了使用方便我们可以去GitHub找一个集成好的依赖:

https://github.com/tobato/FastDFS_Client

<dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId><version>1.27.2</version>
</dependency>

2、将Fdfs配置引入项目

只需要创建一个配置类就可以了:

@Configuration
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class ComponetImport {// 导入依赖组件
}

参考截图:
image-20200816103224502

3、在application.yml当中配置Fdfs相关参数

根据自己情况修改相应ip地址及端口号:

server:port: 8080ip: 10.211.55.4 # 根据自己FastDFS服务器修改fdfs:so-timeout: 1501connect-timeout: 601thumb-image:             #缩略图生成参数width: 150height: 150tracker-list:            #TrackerList参数,支持多个- 10.211.55.4:22122web-server-url: http://${ip}:8888/

4、client封装工具类

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;@Component
public class FastDFSClient {@Autowiredprivate FastFileStorageClient storageClient;@Autowiredprivate 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 文件访问地址* @return*/public void deleteFile(String fileUrl) {if (StringUtils.isEmpty(fileUrl)) {return;}try {StorePath storePath = StorePath.parseFromUrl(fileUrl);storageClient.deleteFile(storePath.getGroup(), storePath.getPath());} catch (FdfsUnsupportStorePathException e) {System.out.println(e.getMessage());// TODO 只是测试,所以未使用,logger,正式环境请修改打印方式}}/*** 下载文件** @param fileUrl 文件URL* @return 文件字节* @throws IOException*/public byte[] downloadFile(String fileUrl) throws IOException {String group = fileUrl.substring(0, fileUrl.indexOf("/"));String path = fileUrl.substring(fileUrl.indexOf("/") + 1);DownloadByteArray downloadByteArray = new DownloadByteArray();byte[] bytes = storageClient.downloadFile(group, path, downloadByteArray);return bytes;}}

5、创建Conttoler测试类

5.1 文件上传测试
@RestController
@RequestMapping("/file")
public class FileUploadController {@Autowiredprivate FastDFSClient fastDFSClient;/*** 上传* @param file* @return* @throws IOException*/@RequestMapping("/upload")public String uploadFile(MultipartFile file) throws IOException {return fastDFSClient.uploadFile(file);}}

执行效果截图:
image-20200816120203238

5.2、下载文件测试

@RestController
@RequestMapping("/file")
public class FileUploadController {@Autowiredprivate FastDFSClient fastDFSClient;/*** 下载* @param fileUrl* @param response* @throws IOException*/@RequestMapping("/download")public void downloadFile(String fileUrl, HttpServletResponse response) throws IOException {byte[] bytes = fastDFSClient.downloadFile(fileUrl);// TODO 这里只是为了整合fastdfs,所以写死了文件格式。需要在上传的时候保存文件名。下载的时候使用对应的格式response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("sb.xlsx", "UTF-8"));response.setCharacterEncoding("UTF-8");ServletOutputStream outputStream = null;try {outputStream = response.getOutputStream();outputStream.write(bytes);} catch (IOException e) {e.printStackTrace();} finally {try {outputStream.flush();outputStream.close();} catch (IOException e) {e.printStackTrace();}}}}

测试下载路径:

http://127.0.0.1:8080/file/download?fileUrl=group1/M00/00/00/CtM3BF84r4SAEPDgAABoGL78QcY682.jpg

拼接的参数为:group1/M00/00/00/CtM3BF84r4SAEPDgAABoGL78QcY682.jpg

大家想修改路径的话,需要同步修改 downloadFile() 方法里的分隔方式。
image-20200816121546634

你知道的越多,不知道的就越多,欢迎关注我的微信公众号:niceyoo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/413943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL取最大值编码(自动编码)

SQL取最大值编码(自动编码) 用途 : 使用SQL语法做出自动编码效果&#xff0c;例如将单号自动1后&#xff0c;产生该笔单号 Table说明 SQL语法 SELECT AREPLICATE(0,7-len(convert(varchar,((MAX(right(ae002,7)))1))))(convert(varchar,((MAX(right(ae002,7)))1))) from ygmae …

[js] 手写一个trim()的方法

[js] 手写一个trim()的方法 function trim(str) { if (str[0] && str[str.length - 1] ) { return trim(str.substring(1, str.length - 1)) } else if (str[0] ! && str[str.length - 1] ) { return trim(str.substring(0, str.length - 1)) } else…

微信小程序里如何使用npm?小程序集成友盟举例

1、执行npm初始化指令 小程序根目录&#xff0c;命令执行如下指令&#xff1a; npm init执行后会让加载项目初始信息&#xff0c;具体截图如下&#xff1a; 2、执行安装npm包指令 在这我们举个例子&#xff0c;以接入友盟统计SDK为例&#xff0c;执行命令如下&#xff1a;…

Spring MVC 5 + Thymeleaf 基于Java配置和注解配置

Spring MVC 5 Thymeleaf 注解配置 Spring的配置方式一般为两种&#xff1a;XML配置和注解配置 Spring从3.0开始以后&#xff0c;推荐使用注解配置&#xff0c;这两种配置的优缺点说的人很多&#xff0c;我就不说了&#xff0c;自行体会&#xff0c;下面就用注解配置实现一个Sp…

[js] 你是如何比较js函数的执行速度的?

[js] 你是如何比较js函数的执行速度的&#xff1f; 采用chrome performance apiconsole.time(flag); console.timeEnd(flag);performance api比较精准的 console.time(flag); 也行 搭配timelog 多次测量个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容…

docker镜像无法删除 Error:No such image:xxxxxx

1、前言 docker镜像无法删除&#xff0c;通过 docker images 查看镜像明明存在就是删除不了。 删除提示&#xff1a;Error&#xff1a;No such image&#xff1a;xxxxxxx 具体截图内容如下&#xff1a; 2、解决方法 进入目录&#xff1a; cd /var/lib/docker/image/over…

[js] axios拦截器原理是什么?

[js] axios拦截器原理是什么&#xff1f; 拦截器原理其实就是用use添加用户自定义的函数到拦截器的数组中。 最后把他们放在拦截器请求前&#xff0c;请求后。组成promise链式调用。 // 组成Promise链// Hook up interceptors middleware// 把 xhr 请求 的 dispatchRequest 和…

python中集合set,字典dict和列表list的区别以及用法

python中set代表集合&#xff0c;list代表列表,dict代表字典 set和dict的区别在于&#xff0c;dict是存储key-value&#xff0c;每一个key都是唯一的&#xff0c;set相对于dict存储的是key&#xff0c;且key是唯一的,list除了变量外都可以存储 dict{"a":1,"b&qu…

[js] fetch和axios请求的原理都是基于XMLHttpRerequst吗?

[js] fetch和axios请求的原理都是基于XMLHttpRerequst吗&#xff1f; axios是基于XMLHttpRequest的封装&#xff0c;而fetch是js原生支持的网络请求api&#xff0c;这在浏览器底层进行了支持。个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#x…

LeetCode(81): 搜索旋转排序数组 II

Medium&#xff01; 题目描述&#xff1a; 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 ( 例如&#xff0c;数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。 编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true&#xff0c;否则返回 false。 示…

网站三级分销数据库如何设计,简单案例

一、问题产生 有小伙伴微信私信我&#xff0c;说老板想设计一套三级返佣的微信淘宝客裂变系统&#xff0c;然后问我怎么搞… 咳咳&#xff0c;对于三级分销的数据库设计&#xff0c;相信很多小伙伴头疼的可能不是设计上&#xff0c;而是查询上&#xff0c;因为通常涉及到会员…

[js] 举例说明面向对象编程有什么缺点?

[js] 举例说明面向对象编程有什么缺点&#xff1f; 有实例化开销&#xff0c;内存消耗比较大&#xff0c;性能消耗比较大个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端…

第6课 仿Siri机器人-语音朗读和语音识别

一、功能设计输入文本&#xff0c;单击“朗读”按钮&#xff0c;由手机读出该文本&#xff08;如果没有输入文本&#xff0c;则弹出消息框警告“请输入文本&#xff09;&#xff1b;单击“识别”按钮&#xff0c;读入语音&#xff0c;从文本框中输出文字。&#xff08;另&#…

口述完SpringMVC执行流程,面试官就让同事回家等消息了

Srping MVC 执行流程真的是老生常谈的话题了&#xff0c;最近同事小刚出去面试&#xff0c;前面面试官相继问了几个 Spring 相关的问题&#xff0c;但当面试官问他&#xff0c;你知道 Srping MVC 的执行流程吗&#xff1f;小刚娴熟的巴拉巴拉回答完后&#xff0c;面试官就让他回…

[js] 使用js实现一个循环队列

[js] 使用js实现一个循环队列 const queue [] let queueRunning false let loopTimer null const loop task > {// do something...console.log(task)if (isQueueHasTask()) {// you can add new tasks in the middle of the queue.loopTimer setTimeout(() > {loo…

iview-cli 采坑记录

1.iview-cli 关于跨域的问题&#xff1a; 使用 webpack-devServer 启动 node 服务器可以通过配置 proxy 对象实现跨域&#xff1a; let proxyUrl http://dev.api.wankaonline.gm825.net;devServer: {proxy: {/index: {target: proxyUrl,pathRewrite: {^/index : /index},ws: t…

如何关闭线程池?会创建不会关闭?调用关闭方法时线程池里的线程如何反应?

前言 相信大家在面试的时候经常会遇到「线程池」相关的问题&#xff0c;比如&#xff1a; 什么是线程池&#xff1f;线程池的优点&#xff1f;有哪几种创建线程池的方式&#xff1f;四种创建线程池的使用场景&#xff1f;线程池的底层原理&#xff1f;线程池相关的参数&#…

[js] Number()的存储空间是多大?假如接口返回一个超过最大字节的数字怎么办?

[js] Number()的存储空间是多大&#xff1f;假如接口返回一个超过最大字节的数字怎么办&#xff1f; Number类型的最大值为2的53次方&#xff0c;即9007199254740992&#xff0c;如果超过这个值&#xff0c;比如900719925474099222&#xff0c;那么得到的值会不精确&#xff0…

C++ 判断系统大小字节序

bool IsLitterEndian() {union UTest{std::uint16_t t;std::uint8_t c;} endianTest{ 0x01 };return (endianTest.c 0x01); } 转载于:https://www.cnblogs.com/fluteary/p/9178627.html

macos brew zookeeper,安装后zookeeper启动失败?

一、Zookeeper安装流程 执行如下安装命令&#xff1a; brew install zookeeper执行截图如下&#xff1a; 安装后查看 zookeeper 安装信息&#xff08;默认拉取最新版本&#xff09; brew info zookeeper执行截图如下&#xff1a; 二、Zookeeper启动、状态查询、及关闭 启…