Spring Boot整合FastDFS,開啓token防盜鏈

FastDFS部署參考這裏

FastDFS_Client使用

添加依賴

FastDFS_Client:項目地址
Simplemagic:項目地址
pom.xml中添加:

        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.27.2</version>
        </dependency>
         <dependency>
            <groupId>com.j256.simplemagic</groupId>
            <artifactId>simplemagic</artifactId>
            <version>1.16</version>
        </dependency>

添加配置類

新建FastDFSConfig.java

@Configuration
@Import(FdfsClientConfig.class)
//解決jmx重複註冊bean的問題
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastDFSConfig {
    // 導入依賴組件
}

修改配置文件

application.properties後面添加:

# 連接超時時長
fdfs.so-timeout = 1501
fdfs.connect-timeout = 601
# traker服務的訪問地址,有多個時用逗號隔開
fdfs.tracker-list = tracker1IP:tracker1Port,tracker2IP:tracker2Port

新建FastDFS工具類

新建FastDFSUtils.java

@Slf4j
@Component
public class FastDFSUtils {
    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    //文件上傳
    public String uploadFile(MultipartFile file) throws Exception {
        log.info("開始上傳文件至FastDFS:{}", file.getName());
        byte[] bytes;
        try {
            bytes = file.getBytes();
        } catch (IOException e) {
            log.error("讀取文件錯誤");
            throw new Exception("讀取文件錯誤");
        }
        //獲取源文件名稱
        String originalFileName = file.getOriginalFilename();
        //獲取文件後綴
        String extension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
        //獲取文件大小
        long fileSize = file.getSize();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        StorePath storePath = fastFileStorageClient.uploadFile(byteArrayInputStream, fileSize, extension, null);
        log.info("文件上傳至FastDFS成功path:{}", storePath.getFullPath());

        return storePath.getFullPath();
    }
    
	//文件上傳(本地文件)
    public String uploadFile(File file) throws Exception {
        log.info("開始上傳文件至FastDFS:{}", file.getName());
        byte[] bytes;
        InputStream inputStream = null;
        try {
            inputStream = openInputStream(file);
            bytes = IOUtils.toByteArray(inputStream, file.length());
        } catch (IOException e) {
            log.error("讀取文件錯誤");
            //關閉輸入流
            IOUtils.closeQuietly(inputStream);
            throw new Exception("讀取文件錯誤");
        }
        //獲取源文件名稱
        String fileName = file.getName();
        //獲取文件後綴
        String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
        //獲取文件大小
        long fileSize = file.length();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        StorePath storePath = fastFileStorageClient.uploadFile(byteArrayInputStream, fileSize, extension, null);
        log.info("文件上傳至FastDFS成功path:{}", storePath.getFullPath());

        //關閉輸入流
        IOUtils.closeQuietly(inputStream);
        return storePath.getFullPath();
    }

    //文件轉輸入流
    public static FileInputStream openInputStream(File file) throws IOException {
        if (file.exists()) {
            if (file.isDirectory()) {
                throw new IOException("文件" + file + "'是一個目錄");
            }
            if (!file.canRead()) {
                throw new IOException("文件" + file + "無法讀取");
            }
        } else {
            throw new FileNotFoundException("文件" + file + "不存在");
        }
        return new FileInputStream(file);
    }

    /**
     * 文件下載
     *
     * @param fileUrl  示例:group1/M00/00/00/oYYBAF6ZsvCAaQzIAABdreSfEnY579.jpg
     */
    public void downloadFile(String fileUrl, HttpServletResponse response) throws Exception {
        //設置ContentType
        response.setContentType(getContentType(fileUrl));
        //設置keep-alive
        response.setHeader("Connection", "keep-alive");
        ServletOutputStream outputStream;
        try {
            //刷新緩衝
            response.flushBuffer();
            //獲取輸出流
            outputStream = response.getOutputStream();
        } catch (IOException e) {
            log.error("獲取輸出流異常", e);
            throw new Exception("獲取輸出流異常");
        }
        //解析url
        StorePath storePath = StorePath.parseFromUrl(fileUrl);
        //下載文件
        DownloadFileStream downloadFileStream = new DownloadFileStream(outputStream);
        fastFileStorageClient.downloadFile(storePath.getGroup(), storePath.getPath(), downloadFileStream);
        //關閉輸出流
        IOUtils.closeQuietly(outputStream);
    }

    /**
     * 文件刪除
     *
     * @param fileUrl 示例:group1/M00/00/00/oYYBAF6ZsvCAaQzIAABdreSfEnY579.jpg
     */
    public void deleteFile(String fileUrl) {
        log.info("刪除FastFDS文件:{}", fileUrl);
        fastFileStorageClient.deleteFile(fileUrl);
    }

    /**
     * 下載文件時獲取ContentType
     *
     * @param fileName 文件名中包含後綴即可
     */
    public String getContentType(String fileName) {
        ContentInfo contentInfo = ContentInfoUtil.findExtensionMatch(fileName);
        if (contentInfo == null) {
            return null;
        }
        return contentInfo.getMimeType();
    }
}

Controller參考代碼

    @Resource
    FastDFSUtils fastDFSUtils;

	//上傳文件,返回示例:group1/M00/00/00/oYYBAF6ZsvCAaQzIAABdreSfEnY579.jpg
    @ApiOperation(value = "up", notes = "")
    @RequestMapping(value = "/up", method = {RequestMethod.POST})
    public String up(MultipartFile file) {
        try {
            return fastDFSUtils.uploadFile(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "fail";
    }

	//下載文件,參數示例:group1/M00/00/00/oYYBAF6ZsvCAaQzIAABdreSfEnY579.jpg
    @ApiOperation(value = "down", notes = "")
    @RequestMapping(value = "/down", method = {RequestMethod.GET})
    public void down(String url, HttpServletResponse response) {
        try {
            try {
                fastDFSUtils.downloadFile(url, response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

使用token防盜鏈

FastDFS服務器開啓token防盜鏈,參考這裏
開啓token後,通過client訪問文件不受影響,通過nginx訪問需要添加token參數

添加依賴

pom.xml中添加:

        <dependency>
            <groupId>net.oschina.zcx7878</groupId>
            <artifactId>fastdfs-client-java</artifactId>
            <version>1.27.0.0</version>
        </dependency>

修改配置文件

application.properties後面添加:

# 開啓token
fdfs.http.anti_steal_token = true
# 服務器配置的secret key
fdfs.http.secret_key = 123456
# 通過nginx訪問fastDFS的地址
fdfs.web-server-url = http://yourIp:port/files/

FastDFS工具類

生成token參考代碼如下:
FastDFSUtils.java中添加:

    @Value("${fdfs.web-server-url}")
    private String fastDfsUrl;

    @Value("${fdfs.http.secret_key}")
    private String fastDfsKey;
    
    /**
     * 獲取帶有token的訪問地址
     *
     * @param fileUrl 示例:group1/M00/00/00/L2ZUml6QisqAUJE3AIOPO1HT6Bo274.mp4
     * @return java.lang.String 示例:http://yourIp:port/files/group1/M00/00/00/L2ZUml6QisqAUJE3AIOPO1HT6Bo274.mp4?token=e9a6ae7f1ecca6fed51e248c6a10d3bc&ts=1589361883
     */
    public String getTokenUrl(String fileUrl) throws Exception {
        String path = StorePath.parseFromUrl(fileUrl).getPath();
        //時間戳 單位爲秒
        int ts = (int) (System.currentTimeMillis() / 1000);
        String token;
        try {
            token = ProtoCommon.getToken(path, ts, fastDfsKey);
        } catch (Exception e) {
           log.error("獲取token異常", e);
           throw new Exception("FastDFS獲取token異常");
        }

        return fastDfsUrl + fileUrl + "?token=" + token + "&ts=" + ts;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章