文件服務-Springboot+FastDFS

前提:

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

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章