SpringBoot2.0集成FastDFS
SpringBoot2.0集成FastDFS
前两篇整体上介绍了通过 Nginx 和 FastDFS 的整合来实现文件服务器。但是,在实际开发中对图片或文件的操作都是通过应用程序来完成的,因此,本篇将介绍 Spring Boot 整合 FastDFS 客户端来实现对图片/文件服务器的访问。
如果有不了解 FastDFS 的读者可以先浏览《CentOS7 安装FastDFS分布式文件系统》或是另行查阅网上相关资料。
一、整合编码
项目整体的代码结构图如下:
添加依赖
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.0.4.RELEASE</version>
- <relativePath /> <!-- lookup parent from repository -->
- </parent>
- <groupId>com.sql.tools</groupId>
- <artifactId>springboot-sql-tools</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <java.version>1.8</java.version>
- <mybatis.spring.version>1.3.2</mybatis.spring.version>
- <com.alibaba.druid.version>1.1.10</com.alibaba.druid.version>
- <log4j.version>1.2.17</log4j.version>
- <pagehelper.version>1.2.5</pagehelper.version>
- <docker.image.prefix>kitty</docker.image.prefix>
- <fastjson.version>1.2.48</fastjson.version>
- <commons-lang3>3.4</commons-lang3>
- <oracle.version>11.2.0.4.0</oracle.version>
- <spring.boot.admin.version>2.0.0</spring.boot.admin.version>
- </properties>
- <dependencies>
- <!-- spring boot -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-log4j2 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-log4j2</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <!-- spring aop -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-aop</artifactId>
- </dependency>
- <!-- mybatis -->
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>${mybatis.spring.version}</version>
- </dependency>
- <!-- mysql -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- </dependency>
- <!-- https://mvnrepository.com/artifact/com.oracle/ojdbc6 -->
- <dependency>
- <groupId>com.oracle</groupId>
- <artifactId>ojdbc6</artifactId>
- <version>${oracle.version}</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>${com.alibaba.druid.version}</version>
- </dependency>
- <!-- log4j -->
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>${log4j.version}</version>
- </dependency>
- <!-- swagger -->
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger2</artifactId>
- <version>2.8.0</version>
- </dependency>
- <dependency>
- <groupId>io.springfox</groupId>
- <artifactId>springfox-swagger-ui</artifactId>
- <version>2.8.0</version>
- </dependency>
- <!-- pagehelper -->
- <dependency>
- <groupId>com.github.pagehelper</groupId>
- <artifactId>pagehelper-spring-boot-starter</artifactId>
- <version>${pagehelper.version}</version>
- </dependency>
- <!-- fastjson -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>${fastjson.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <!-- https://mvnrepository.com/artifact/net.oschina.zcx7878/fastdfs-client-java -->
- <!-- fastdfs-client-java -->
- <dependency>
- <groupId>com.github.tobato</groupId>
- <artifactId>fastdfs-client</artifactId>
- <version>1.26.5</version>
- <exclusions>
- <exclusion>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- <!-- 打包时拷贝MyBatis的映射文件 -->
- <resources>
- <resource>
- <directory>src/main/java</directory>
- <includes>
- <include>**/sqlmap/*.xml</include>
- </includes>
- <filtering>false</filtering>
- </resource>
- <resource>
- <directory>src/main/resources</directory>
- <includes>
- <include>**/*.*</include>
- </includes>
- <filtering>true</filtering>
- </resource>
- </resources>
- </build>
- </project>
我在里面添加了Mybatis和数据连接驱动,使用的日志系统是Solf4j
,log4j2
配置文件如下:
application.yml
- # Tomcat
- server:
- tomcat:
- uri-encoding: UTF-8
- max-threads: 1000
- min-spare-threads: 30
- port: 8001
- session:
- timeout:7200
- context-path: /lion-admin
- # DataSource
- spring:
- datasource:
- name: druidDataSource
- type: com.alibaba.druid.pool.DruidDataSource
- druid:
- driver-class-name: oracle.jdbc.driver.OracleDriver
- url: jdbc:oracle:thin:@192.168.0.205:1521:orcl
- username: gcloud_check
- password: gcloud_check
- filters: stat,wall,log4j,config
- max-active: 100
- initial-size: 1
- max-wait: 60000
- min-idle: 1
- time-between-eviction-runs-millis: 60000
- min-evictable-idle-time-millis: 300000
- validation-query: select 'x' FROM DUAL
- test-while-idle: true
- test-on-borrow: false
- test-on-return: false
- pool-prepared-statements: true
- max-open-prepared-statements: 50
- max-pool-prepared-statement-per-connection-size: 20
- # FastDFS
- # ===================================================================
- # 分布式文件系统FDFS配置
- # ===================================================================
- fdfs:
- so-timeout: 1501
- connect-timeout: 601
- thumb-image: #缩略图生成参数
- width: 150
- height: 150
- web-server-url: 192.168.0.137/
- tracker-list: 192.168.0.137:22122
端口:8001
数据使用的是:Oracle
注意: FastDFS的第三方客户端包引入的时候要去除logback的包,不然与log4j2冲突,启动会报错
- <dependency>
- <groupId>com.github.tobato</groupId>
- <artifactId>fastdfs-client</artifactId>
- <version>1.26.5</version>
- <exclusions>
- <exclusion>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
上边的 fastdfs-client 是并非 FastDFS Client 原作者编写的整合包,具体详情可以访问 https://github.com/tobato/FastDFS_Client
log4j2-spring.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!--设置log4j2的自身log级别为warn-->
- <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
- <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,
- 当设置成trace时,你会看到log4j2内部各种详细输出-->
- <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
- <configuration status="warn" monitorInterval="30">
- <!--先定义所有的appender-->
- <appenders>
- <!--这个输出控制台的配置-->
- <console name="Console" target="SYSTEM_OUT">
- <!--输出日志的格式-->
- <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
- </console>
- <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
- <File name="log" fileName="log/test.log" append="false">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
- </File>
- <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,
- 则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
- <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/hpaasvc/info.log"
- filePattern="${sys:user.home}/logs/hpaasvc/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
- <Filters>
- <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
- <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
- <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
- </Filters>
- <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
- <Policies>
- <TimeBasedTriggeringPolicy/>
- <SizeBasedTriggeringPolicy size="100 MB"/>
- </Policies>
- </RollingFile>
- <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/hpaasvc/warn.log"
- filePattern="${sys:user.home}/logs/hpaasvc/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
- <Filters>
- <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
- <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
- </Filters>
- <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
- <Policies>
- <TimeBasedTriggeringPolicy/>
- <SizeBasedTriggeringPolicy size="100 MB"/>
- </Policies>
- <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
- <DefaultRolloverStrategy max="20"/>
- </RollingFile>
- <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/hpaasvc/error.log"
- filePattern="${sys:user.home}/logs/hpaasvc/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
- <ThresholdFilter level="ERROR"/>
- <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
- <Policies>
- <TimeBasedTriggeringPolicy/>
- <SizeBasedTriggeringPolicy size="100 MB"/>
- </Policies>
- </RollingFile>
- </appenders>
- <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
- <loggers>
- <!--过滤掉spring和hibernate的一些无用的debug信息-->
- <logger name="org.springframework" level="INFO">
- </logger>
- <logger name="org.mybatis" level="INFO">
- </logger>
- <root level="INFO">
- <appender-ref ref="Console"/>
- <appender-ref ref="RollingFileInfo"/>
- <appender-ref ref="RollingFileWarn"/>
- <appender-ref ref="RollingFileError"/>
- </root>
- </loggers>
- </configuration>
或者看这边配置log4j2的整合文章SpringBoot 2.0 的Log4j2日志信息配置
代码
- /**
- * @author lr
- * @date 2018年12月26日 下午4:28:14
- * @version V1.0.0
- */
- package com.louis.sql.tools;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.context.annotation.ComponentScan;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.EnableMBeanExport;
- import org.springframework.jmx.support.RegistrationPolicy;
- @Configuration
- @ComponentScan
- @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
- @SpringBootApplication
- public class ToolsApplication {
- public static void main(String[] args) {
- SpringApplication.run(ToolsApplication.class, args);
- }
- }
FastDFSClient.java
- /**
- * @author lr
- * @date 2019年1月28日 下午1:41:39
- * @version V1.0.0
- */
- package com.louis.sql.tools.config;
- import java.io.ByteArrayInputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.nio.charset.Charset;
- import org.apache.commons.io.FilenameUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import org.springframework.web.multipart.MultipartFile;
- 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;
- @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.parseFromUrl(fileUrl);
- storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
- } catch (FdfsUnsupportStorePathException e) {
- logger.warn(e.getMessage());
- }
- }
- }
controller
- /**
- * @author lr
- * @date 2019年1月28日 下午1:50:47
- * @version V1.0.0
- */
- package com.louis.sql.tools.controller;
- import java.net.URLEncoder;
- import java.util.HashMap;
- import java.util.Map;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.commons.io.IOUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- import org.springframework.web.multipart.MultipartFile;
- import com.louis.sql.tools.config.FastDFSClient;
- @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);
- }
- }
测试效果
然后通过swagger-ui的接口直接测试文件上传功能
访问地址:[swagger-ui首页]http://localhost:8001/swagger-ui.html#
如果需要看源码:https://github.com/PlayTaoist/SpringBoot2-FastDFS
新博客地址:https://www.codepeople.cn/
=======================================================================================
微信公众号:
SpringBoot2.0集成FastDFS的更多相关文章
- (补漏)Springboot2.0 集成shiro权限管理
原文Springboot2.0 集成shiro权限管理 一.关于停止使用外键. 原本集成shiro建立用户.角色.权限表的时候使用了外键,系统自动创建其中两个关联表,用@JoinTable.看起来省事 ...
- SpringBoot2.0集成Shiro
1.shiro的三个核心概念: 1)Subject:代表当前正在执行操作的用户,但Subject代表的可以是人,也可以是任何第三方系统帐号.当然每个subject实例都会被绑定到SercurityMa ...
- springboot2.0集成shiro出现ShiroDialect报错找不到AbstractTextChildModifierAttrPr
@Bean public ShiroDialect shiroDialect() { return new ShiroDialect(); } 报错出现找不到org/thymeleaf/process ...
- SpringBoot2.0 整合 FastDFS 中间件,实现文件分布式管理
本文源码:GitHub·点这里 || GitEE·点这里 一.FastDFS简介 1.FastDFS作用 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步 ...
- springboot2.0结合fastdfs实现文件分布式上传
1. 引入依赖 在父工程中,我们已经管理了依赖,版本为: <fastDFS.client.version>1.26.7</fastDFS.client.version> 因此, ...
- springboot2.0 集成elasticsearch,实现检索、分页、排序
springboot整合es的方式: transport方式(7.0弃用,8.0移除) spring-data(完全当做数据库来用,无法全部支持es,内部也是基于transport,包装后使用非常简单 ...
- Springboot2.0 集成shiro权限管理
在springboot中结合shiro教程搭建权限管理,其中几个小细节的地方对新手不友好,伸手党更是无法直接运行代码,搭建过程容易遇坑,记录一下.关键的地方也给注释了. 版本:springboot版本 ...
- SpringBoot2.0集成WebSocket,实现后台向前端推送信息
感谢作者,支持原创: https://blog.csdn.net/moshowgame/article/details/80275084 什么是WebSocket? WebSocket协议是基于TCP ...
- springboot2.0集成webSocket
WebSocket和http的区别? http协议是用在应用层的协议,他是基于tcp协议的,http协议建立链接也必须要有三次握手才能发送信息. http链接分为短链接,长链接,短链接是每次请求都要三 ...
随机推荐
- loadrunner之运行方式:线程还是进程?
loadrunner controller将使用驱动程序mmdrv运行Vuser. 用户可以在controller的run-time setting中选择Vuser的运行方式: 是多进程方式还是多线程 ...
- mniui里面没有只显示年的控件,monthpicker显示年月,datepicker显示具体到天的日期
spinner无法出现下拉框,只能一下下的点击. combobox可以出现下拉框,但是一般情况是从url后台取值. 现在可以自己在js里定义需要的值. <td><input id=& ...
- 机器学习实战笔记-k-近邻算法
机器学习实战笔记-k-近邻算法 目录 1. k-近邻算法概述 2. 示例:使用k-近邻算法改进约会网站的配对效果 3. 示例:手写识别系统 4. 小结 本章介绍了<机器学习实战>这本书中的 ...
- SpringBoot使用LomBok
Lombok是什么?它是一个能帮我们消除那些必须要写但是重复的代码,比如setter,getter,构造函数之类的方法. 首先先简单说一下idea安装lombok,有2种方法: 1.直接从http:/ ...
- thinkpad那些事儿
之前玩过windows系统的acer笔记本,联想台式机,os系统的mac pro笔记本,最近刚接触windows系统的thinkpad笔记本,对它的键盘触感印象深刻,舒服.thinkpad,思考本,是 ...
- 【树形期望DP】BZOJ3566- [SHOI2014]概率充电器
[题目大意] 充电器由 n-1 条导线连通了 n 个充电元件.这n-1条导线均有一个通电概率p%,而每个充电元件本身有直接被充电的概率q[i]%.问期望有多少个充电元件处于充电状态? [思路] 第一次 ...
- IntelliJ IDEA使用教程(简介)
最智能的IDE IDEA 全称IntelliJ IDEA 是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构.J2EE支 ...
- 【ACM】 1231 最大连续子序列
[1231 最大连续子序列 ** Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- pip命令无法使用
今天在学习Python时需要安装Requests 使用命令:pip install requests 提示错误 我的解决办法是: cmd 切换到Python安装路径中的scripts ...
- 冲刺NOIP复习,算法知识点总结
前言 离NOIP还有一个星期,匆忙的把整理的算法补充完善,看着当时的整理觉得那时还年少.第二页贴了几张从贴吧里找来的图片,看着就很热血的.当年来学这个竞赛就是为了兴趣,感受计算机之美的. ...