springboot整合fastdfs-client操作fastdfs文件服务器

springboot与fastdfs-client的整合

为Java操作fastdfs文件服务器提供的第三方工具:

​ GitHub源码: https://github.com/tobato/FastDFS_Client

注意:fastdfs-client 1.26.4版本以前的配置略有不同,具体参见上传文档。

1.pom.xml引入第三方工具类:
<dependency>
    <groupId>com.github.tobato</groupId>
    <artifactId>fastdfs-client</artifactId>
    <version>1.26.6</version>
</dependency>
2.在application.yml引入配置:
fdfs:
   soTimeout: 1500 			# socket连接超时时长
   connectTimeout: 600 		# 连接tracker服务器超时时长
   reqHost: xxx.xxx.xxx.xxx # nginx访问地址
   reqPort: 80              # nginx访问端口
   thumbImage: 				# 缩略图的宽高
       width: 150
       height: 150
trackerList: 				# tracker服务配置地址列表,替换成自己服务的IP地址,支持多个
      - xxx.xxx.xxx.xxx:22122
3.写个工具类 FastFileStorageClientUtil:
  • 上传文件带MetaData
  • 上传文件不带MetaData
  • 上传图片并生成缩略图
  • 下载文件
  • 删除文件
package com.myt.fdfs.utils;
/*省略import*/
/**
 * FastFileStorageClient客户端
 * @author: mayating
 * @create: 2020-12-25 11:36
 */
@Component
public class FastFileStorageClientUtil {

    @Autowired
    protected FastFileStorageClient storageClient;

    @Autowired
    private ThumbImageConfig thumbImageConfig;

    @Value("${fdfs.reqHost}")
    private String reqHost;

    @Value("${fdfs.reqPort}")
    private String reqPort;

    /**
     * 日志
     */
    protected static Logger LOGGER = LoggerFactory.getLogger(FastFileStorageClientUtil.class);


    /*******************************************上传文件/图片***********************************************************/

    /**
     * 上传文件 并且设置 MetaData
     * @param file
     * @param metaDataSet
     * @return
     */
    public String uploadFileAndMetaData(MultipartFile file,Set<MetaData> metaDataSet){
        InputStream in = null;
        try {
            in = file.getInputStream();
            //上传文件和MetaData
            StorePath storePath = storageClient.uploadFile(in, file.getSize(),
                    FilenameUtils.getExtension(file.getOriginalFilename()), metaDataSet);
            //获取 MetaData
            //Set<MetaData> metadata = storageClient.getMetadata(storePath.getGroup(), storePath.getPath());
            //删除文件
            //storageClient.deleteFile(storePath.getGroup(),storePath.getPath());

            //上传文件路径
            return getResAccessUrl(storePath);
        } catch (IOException e) {
            LOGGER.error("文件上传失败:" + e.getMessage());
            //throw new CustomException("文件上传失败:" + e.getMessage());
        }
        return null;
    }

    /**
     * 上传文件 不带 MetaData
     * @param file
     * @return
     */
    public String uploadFileWithOutMetaData(MultipartFile file){
        InputStream in = null;
        try {
            in = file.getInputStream();
            //上传文件和MetaData
            StorePath storePath = storageClient.uploadFile(in, file.getSize(),
                    FilenameUtils.getExtension(file.getOriginalFilename()), null);
            //删除文件
            //storageClient.deleteFile(storePath.getGroup(),storePath.getPath());
            String fileUrl = getResAccessUrl(storePath);
            LOGGER.info("上传文件可访问路径:" + fileUrl);
            //上传文件路径
            return fileUrl;
        } catch (IOException e) {
            LOGGER.error("文件上传失败:" + e.getMessage());
            //throw new CustomException("文件上传失败:" + e.getMessage());
        }
        return null;
    }

    /**
     * 上传图片 并 生成缩略图
     * 缩略图为上传文件名 + 缩略图后缀 _150×150,如xxx.jpg,缩略图为 xxx_150×150.jpg
     *
     * 实际样例如下:
     *      http://localhost:8098/M00/00/17/rBEAAl33pQaAWNQNAAHYvQQn-YE374.jpg
     *      http://localhost:8098/M00/00/17/rBEAAl33pQaAWNQNAAHYvQQn-YE374_150x150.jpg
     * @param file
     * @return
     */
    public String uploadImageAndCrtThumbImage(MultipartFile file){
        StorePath storePath = null;
        InputStream in = null;
        //StringBuilder stringBuilder = new StringBuilder();
        try {
            in = file.getInputStream();
            storePath = storageClient.uploadImageAndCrtThumbImage(in, file.getSize(),
                    FilenameUtils.getExtension(file.getOriginalFilename()), null);
            //获取从文件路径  即缩略图路径
            String slavePath = thumbImageConfig.getThumbImagePath(storePath.getPath());
            String masterUrl = getResAccessUrl(storePath);
            LOGGER.info("图片路径:" + storePath);
            LOGGER.info("图片可访问路径:" + masterUrl);
            LOGGER.info("缩略图路径:" + slavePath);
            return masterUrl;
        } catch (IOException e) {
            LOGGER.error("上传图片及生成缩略图失败:" + e.getMessage());
        }finally {
            //关流
            if(null != in){
                try {
                    in.close();
                } catch (IOException e) {
                    LOGGER.error("输入流关闭失败:" + e.getMessage());
                }
            }
        }
        return null;
    }


    /*******************************************下载文件**********************************************************/

    /**
     * 下载文件
     * @param groupName
     * @param path
     * @return
     */
    public InputStream download(String groupName, String path ) {
        InputStream ins = null;
        try {
            ins =  storageClient.downloadFile(groupName, path, new DownloadCallback<InputStream>(){
                @Override
                public InputStream recv(InputStream ins) throws IOException {
                    // 将此ins返回给上面的ins
                    return ins;
                }}) ;
        }catch (FdfsServerException e){
            //不起作用
            LOGGER.error("文件不存在,下载失败:" + e.getErrorCode());
            throw new CustomException("文件不存在,下载失败:" + e.getErrorCode());
        }
        return null ;
    }

    /*******************************************删除文件**********************************************************/
    public void delFile(String filePath) {
        storageClient.deleteFile(filePath);
    }


    /*******************************************公共方法**********************************************************/

    /**
     * 创建 元数据
     * @return
     */
    private Set<MetaData> createMetaData() {
        Set<MetaData> metaDataSet = new HashSet<>();
        metaDataSet.add(new MetaData("Author", "tobato"));
        metaDataSet.add(new MetaData("CreateDate", "2016-01-05"));
        return metaDataSet;
    }

    /**
     * 封装文件完整URL地址
     * @param storePath
     * @return
     */
    private String getResAccessUrl(StorePath storePath) {
        String fileUrl = "http://" + reqHost + ":" + reqPort + "/" + storePath.getFullPath();
        return fileUrl;
    }

}
4.在controller层使用工具类:
  • 上传图片并生成缩略图
  • 上传文件
  • 下载文件
  • 删除文件
package com.myt.fdfs.controller;
/*省略import*/

/**
 * @author: mayating
 * @create: 2020-12-25 13:49
 */
@RestController
@RequestMapping("/files")
public class UploadController {

    @Autowired
    private FastFileStorageClientUtil dfsClient;


    /**
     * 上传图片并生成缩略图
     * @param file
     * @return
     */
    @PostMapping("/fdfsUploadImage")
    public Result fdfsUploadImage(@RequestParam("file")MultipartFile file){
        String fileUrl = dfsClient.uploadImageAndCrtThumbImage(file);
        return Result.SUCCESS(fileUrl);
    }

    /**
     * 上传文件
     * @param file
     * @return
     */
    @PostMapping("/fdfsUploadFile")
    public Result fdfsUploadFile(@RequestParam("file")MultipartFile file){
        String fileUrl = dfsClient.uploadFileWithOutMetaData(file);
        return Result.SUCCESS(fileUrl);
    }


    /**
     * 下载文件
     *     请求示例地址: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);
        //输入流
        InputStream input = dfsClient.download(groupName, path);
        
        String fileName = paths[paths.length - 1];

        //设置 response的响应头  能跳出下载窗口
        //1.设置响应类型:
        //获取文件的mime类型:content-type
        String mimeType = request.getServletContext().getMimeType(fileName);
        response.setHeader("content-type",mimeType);

        //2.设置响应头打开方式:content-disposition
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

        //获取绑定了客户端的流
        ServletOutputStream output = response.getOutputStream();

        // 把输入流中的数据写入到输出流中
        IOUtils.copy(input, output);
        input.close();
    }

    /**
     * 删除文件
     * 请求地址示例:
     *      http://localhost/deleteFile?filePath=group1/M00/00/00/wKgIZVzZaRiAZemtAARpYjHP9j4930.jpg
     * @param filePath
     * @return
     */
    @GetMapping("/deleteFile")
    public Result delFile(String filePath){
        dfsClient.delFile(filePath);
        return Result.SUCCESS("文件删除成功");
    }

}
5.测试使用
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值