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碼查詢到下載地址,即是接口地址

 

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