File Services -Springboot + FastDFS

premise:

FastDSF first ensure that the service side, has been installed here describes how to integrate with Springboot
friends if you want to install, please refer to this article FastDFS- Installation Guide

Integration of ideas:

Would like nothing more than to complete the integration with Springboot three strides, other components also applies this idea:

1. Add dependence
2. Add configuration class
3. Add related annotations

1. Add dependence

  <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. Add the configuration and notes

Write 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 class configuration, used herein omitted lombok get, set method

@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;
}

Cross-domain configuration:

/**
* @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. Write operation FastDFS Tools

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. Write Controller Controller

Here CommonResult results package according to your system inside the framework can be defined, here is my configuration, modify yourself! Please modify yourself! Please modify yourself!

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

}

Published 24 original articles · won praise 42 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_42875895/article/details/104614961