前提:
先保证FastDSF服务端,已安装完毕 此处介绍如何与Springboot进行整合
若需要安装的朋友们,请参照这一篇文章 FastDFS-安装篇
整合思路:
想完成与Springboot 整合无非就是三大步,其他组件同样适用此思路:
1. 添加依赖
2. 添加配置类
3. 添加相关注解
1.添加依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<!--Springboot-Web服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--FastDFS -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.5</version>
</dependency>
<!--lombok小辣椒-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
</dependencies>
2.添加配置和注解
编写yml
server:
port: 8001
spring:
application:
name: fastdfs-service
servlet:
multipart:
max-file-size: 100MB # 最大支持文件大小
max-request-size: 100MB # 最大支持请求大小
# 分布式文件系统FDFS配置
fdfs:
soTimeout: 1500 #socket连接超时时长
connectTimeout: 600 #连接tracker服务器超时时长
reqHost: 39.107.35.76 #nginx访问地址
reqPort: 80 #nginx访问端口
trackerList: #TrackerList参数,支持多个,我这里只有一个,如果有多个在下方加- x.x.x.x:port
- 39.107.35.76:22122
FastDfsConfig 配置类,此处使用lombok 省略get,set方法
@Data
@Configuration
/**
* 导入FastDFS-Client组件
*/
@Import(FdfsClientConfig.class)
/**
解决jmx重复注册bean的问题
*
*/
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
/**
* @author: lujie
* @create: 2020/2/23
* @description: FastDfsConfig FastDFS配置类
**/
@ConfigurationProperties(prefix = "fdfs")
public class FastDfsConfig {
private Long soTimeout;
private Long connectTimeout;
private String reqHost;
private Long reqPort;
}
跨域配置:
/**
* @author: lujie
* @create: 2020/2/20
* @description: 全局跨域配置
**/
@Configuration
public class GlobalCorsConfig {
/**
* 允许跨域调用的过滤器
*/
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
//允许所有域名进行跨域调用
config.addAllowedOrigin("*");
//允许跨越发送cookie
config.setAllowCredentials(true);
//放行全部原始头信息
config.addAllowedHeader("*");
//允许所有请求方法跨域调用
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
3.编写操作FastDFS工具类
package com.sol.admin.utils;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadCallback;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.sol.admin.entity.FileInfo;
import com.sol.admin.exception.ApiAssert;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
/**
* @author: lujie
* @create: 2020/2/23
* @description: FastDFSClientUtil FastDfs 客户端连接工具类
**/
@Component
public class FastDFSClientUtil {
@Value("${fdfs.reqHost}")
private String reqHost;
@Value("${fdfs.reqPort}")
private String reqPort;
@Resource
private FastFileStorageClient storageClient;
/**
* 文件上传
* @param file
* @return
* @throws IOException
*/
public FileInfo uploadFile(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadFile(file.getInputStream(),file.getSize(),
FilenameUtils.getExtension(file.getOriginalFilename()),null);
String fileType = StrUtil.subAfter(file.getOriginalFilename(), ".", true);
FileInfo fileInfo = FileInfo.builder().fileId(storePath.getFullPath())
.fileName(file.getOriginalFilename())
.fileSize(file.getSize())
.fileType(fileType)
.filePath(getResAccessUrl(storePath))
.build();
return fileInfo;
}
/**
* 文件删除
* @param filePath
*/
public void delFile(String filePath) {
storageClient.deleteFile(filePath);
}
/**
* 文件下载
* @param groupName
* @param path
* @return
*/
public InputStream download(String groupName, String path ) {
InputStream ins = storageClient.downloadFile(groupName, path, new DownloadCallback<InputStream>(){
@Override
public InputStream recv(InputStream ins) throws IOException {
// 将此ins返回给上面的ins
return ins;
}}) ;
return ins ;
}
/**
* 封装文件完整URL地址
* @param storePath
* @return
*/
private String getResAccessUrl(StorePath storePath) {
String fileUrl = "http://" + reqHost + ":" + reqPort + "/" + storePath.getFullPath();
return fileUrl;
}
}
4.编写Controller控制器
此处CommonResult 结果封装可根据你系统框架 里面的定义即可,此处是我的配置,请自行修改!请自行修改!请自行修改!
package com.sol.admin.controller;
import com.sol.admin.api.CommonResult;
import com.sol.admin.entity.FileInfo;
import com.sol.admin.exception.ApiAssert;
import com.sol.admin.utils.FastDFSClientUtil;
import org.apache.commons.io.IOUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
/**
* @author: lujie
* @create: 2020/2/23
* @description: FileServiceController 文件处理控制器
**/
@RestController
public class FileServiceController {
@Resource
private FastDFSClientUtil dfsClient;
/**
* 上传文件
* @param file
* @param request
* @return
* @throws IOException
*/
@PostMapping("/upload")
public CommonResult<FileInfo> fdfsUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
ApiAssert.isTrue(file.isEmpty(),"请上传文件");
FileInfo fileInfo = dfsClient.uploadFile(file);
return CommonResult.SUCCESS(fileInfo);
}
/**
* 文件下载
* http://localhost/download?filePath=group1/M00/00/00/wKgIZVzZEF2ATP08ABC9j8AnNSs744.jpg
* @param filePath
* @param request
* @param response
* @throws IOException
*/
@GetMapping("/download")
public void download(String filePath , HttpServletRequest request , HttpServletResponse response) throws IOException {
// group1/M00/00/00/wKgIZVzZEF2ATP08ABC9j8AnNSs744.jpg
String[] paths = filePath.split("/");
String groupName = null ;
for (String item : paths) {
if (item.indexOf("group") != -1) {
groupName = item;
break ;
}
}
String path = filePath.substring(filePath.indexOf(groupName) + groupName.length() + 1, filePath.length());
InputStream input = dfsClient.download(groupName, path);
//根据文件名获取 MIME 类型
String fileName = paths[paths.length-1] ;
System.out.println("fileName :" + fileName);
String contentType = request.getServletContext().getMimeType(fileName);
String contentDisposition = "attachment;filename=" + fileName;
// 设置头
response.setHeader("Content-Type",contentType);
response.setHeader("Content-Disposition",contentDisposition);
// 获取绑定了客户端的流
ServletOutputStream output = response.getOutputStream();
// 把输入流中的数据写入到输出流中
IOUtils.copy(input,output);
input.close();
}
/**
* 删除文件
* @param id
* @return
*/
@GetMapping("/delete")
public CommonResult deleteFile(String id){
ApiAssert.isBlank(id,"缺少文件ID参数");
dfsClient.delFile(id);
return CommonResult.SUCCESS();
}
}