前提:
先保證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();
}
}