Java调用FastDFS上传文件

       以往开发的时候都是使用的Apache服务器进行文件上传,后面改用了Ftp,现在开始接触FastDFS了,感觉还是FastDFS要高级一点,毕竟是分布式文件系统,从性能和稳定性上都有很高的保证。

      搭建docker版本的FastDFS可以参考前面的文章 

       https://blog.csdn.net/monkeyblog/article/details/106121070


      简介

       FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。 
FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。 
       Tracker Server:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。 
       Storage Server:存储服务器,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。 
       Client:客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。
 


     话不多说了,直接上代码了。我的框架是springboot 。


 application.yml

fdfs:
  #回显时的服务器地址,端口是fdfs默认的8888,这里我没有进行修改哦,注意哦~
  file-host: http://172.16.24.203:8888/
  tracker-list:
    - 172.16.24.203:22122   #这里是上传的服务器地址,配置的是22122端口
  so-timeout: 5000
  pool:
    max-total: 200
    max-total-per-key: 50
    max-wait-millis: 5000

  Java代码

  controller

package com.github.edu.modular.edu.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.edu.core.base.controller.BaseController;
import com.github.edu.modular.edu.model.Attachment;
import com.github.edu.modular.edu.service.IAttachmentService;
import com.github.edu.modular.edu.util.ExceptionUtil;
import com.github.edu.modular.edu.util.FileUtil;
import com.github.edu.modular.edu.util.MultipartFileUtil;
import com.github.edu.modular.edu.util.R;
import com.luhuiguo.fastdfs.service.FastFileStorageClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;

/**
 * attachment控制器
 *
 * @author Monkey
 * @Date 2020-04-19 13:20:14
 */
@RestController
@RequestMapping("/attachment")
@Api(value = "Attachment-controller", description = "附件(完成)")
public class AttachmentController extends BaseController {


    @Autowired
    private IAttachmentService attachmentService;

    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    /**
     * 下载,只支持小文件,适合播放类接口
     * @param response
     * @param filecode
     * @throws Exception
     */
    @GetMapping("/play/download/filecode/{filecode}")
    @ApiOperation(value = "下载附件(完成)", notes = "下载附件(完成)")
    public void downloadAttachment(HttpServletResponse response, @PathVariable String filecode) throws Exception{
        Attachment attachment = attachmentService.selectOne(new EntityWrapper<Attachment>()
                .eq("attachment_file_code", filecode)
        );
        if(Objects.isNull(attachment)){
            throw new Exception("不是有效的文件地址");
        }
        String attachmentUrl = attachment.getAttachmentUrl();
        String group = attachmentUrl.substring(0, attachmentUrl.indexOf("/"));
        String path = attachmentUrl.substring(attachmentUrl.indexOf("/") + 1);
        //通过直接下载(大文件会导致超时)
        FileUtil.downloadFile(response, attachment.getAttachmentName(), fastFileStorageClient.downloadFile(group, path));
    }

    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "上传工单附件(完成)", notes = "上传工单附件(完成)")
    public Object uploadFile( @ApiParam("工单附件") MultipartFile file,
                              @ApiParam(value = "附件类型:1.工单 2.题目")@RequestParam(value = "attachmentType", defaultValue = "2", required = false)String attachmentType){
        R r = new R();
        try {
            if (file != null) {

                List<Attachment> attachments = new ArrayList<>();
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                File file1 = MultipartFileUtil.multipartFileToFile(file);
                Attachment attachment = attachmentService.fileSave(file1, uuid);
                attachment.setAttachmentType(attachmentType);
                attachments.add(attachment);
                //删除临时文件
                MultipartFileUtil.delteTempFile(file1);

                attachmentService.insertBatch(attachments);
                Map map = new HashMap<>();
                map.put("attachmentCode", uuid);
                r.setData(map);

            } else {
                r = new R(null,"附件不能为空!", R.FAIL);
            }

        } catch (Exception e) {
            r = ExceptionUtil.getException(e);
        }

        return r;
    }
}

service 

package com.github.edu.modular.edu.service.impl;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.edu.modular.edu.model.Attachment;
import com.github.edu.modular.edu.service.IAttachmentService;
import com.luhuiguo.fastdfs.domain.StorePath;
import com.luhuiguo.fastdfs.service.FastFileStorageClient;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.UUID;


/**
 * attachmentService
 *
 * @author Monkey
 * @Date 2020-04-19 13:20:14
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AttachmentServiceImpl extends ServiceImpl<BaseMapper<Attachment>,Attachment> implements IAttachmentService {

    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    @Override
    public Attachment fileSave(File f, String code) throws Exception {
        String fileCode = UUID.randomUUID().toString();
        String newFilename = fileCode + "." + FilenameUtils.getExtension(f.getName());
        StorePath storePath = fastFileStorageClient.uploadFile(FileUtils.readFileToByteArray(f), newFilename);

        Attachment attachment1 = new Attachment();
        attachment1.setAttachmentUrl(storePath.getFullPath());
        attachment1.setAttachmentCode(code);
        attachment1.setAttachmentFileCode(fileCode.replaceAll("-", ""));
        attachment1.setAttachmentDownloadUrl(("attachment/play/download/filecode/" + fileCode).replaceAll("-", ""));
        attachment1.setAttachmentName(f.getName());
        attachment1.setAttachmentType("1");

        return attachment1;
    }
}

util

package com.github.edu.modular.edu.util; /**
 * Created by TongGuoBo on 2019/6/19.
 */

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @ClassName MultipartFileToFile
 * @Description MultipartFile转fie
 * @Author Monkey
 * @Date 2019/6/19 13:48
 **/
public class MultipartFileUtil {
 
    /**
     * MultipartFile 转 File
     *
     * @param file
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile file) throws Exception {
 
        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }
 
    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 删除本地临时文件
     * @param file
     */
    public static void delteTempFile(File file) {
    if (file != null) {
        File del = new File(file.toURI());
        del.delete();
    }
}
}
package com.github.edu.modular.edu.util;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;

public class FileUtil {

    /**
     * 下载公共配置
     * @param response
     * @param fileName
     * @throws Exception
     */
    public static void downloadSetting(HttpServletResponse response, String fileName) throws Exception{
        // 配置文件下载
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        // 下载文件能正常显示中文
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
    }

    /**
     * 下载文件
     * @param response
     * @param fileName
     *      文件名
     * @param data
     *      下载数据
     * @throws Exception
     */
    public static void downloadFile(HttpServletResponse response, String fileName, byte[] data) throws Exception{
        downloadSetting(response,fileName);
        //实现下载
        OutputStream os = response.getOutputStream();
        os.write(data);
        os.flush();
    }
}

db

CREATE TABLE `attachment` (
  `attachment_id` int(11) NOT NULL AUTO_INCREMENT,
  `attachment_task_id` int(11) DEFAULT NULL COMMENT '问题分类id',
  `attachment_code` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '附件code',
  `attachment_file_code` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '文件编号',
  `attachment_url` varchar(256) COLLATE utf8_bin DEFAULT NULL COMMENT '请求地址',
  `attachment_name` varchar(256) COLLATE utf8_bin DEFAULT NULL COMMENT '附件名字',
  `attachment_type` varchar(2) COLLATE utf8_bin DEFAULT '1' COMMENT '附件类型:1.工单 2.题目',
  `attachment_download_url` varchar(256) COLLATE utf8_bin DEFAULT NULL COMMENT '下载地址',
  `attachment_create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `attachment_update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `attachment_create_by` int(11) DEFAULT NULL COMMENT '创建人',
  `attachment_update_by` int(11) DEFAULT NULL COMMENT '修改人',
  PRIMARY KEY (`attachment_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='附件';

swagger

通过code码查询到下载地址,即是接口地址

 

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