本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(1)

docker容器+fastdfs搭建文件服务器--springboot整合文件服务器实现文件上传, 下载, 删除

发布于2021-03-13 14:06     阅读(1080)     评论(0)     点赞(25)     收藏(5)


Linux安装docker

docker拉取fastdfs镜像

在这里插入图片描述
该镜像已经整合了nginx
在这里插入图片描述

构建容器

构建tracker容器(跟踪服务器,起到调度的作用)

创建挂载目录, 将tracker容器中的/var/fdfs 文件挂载到自己Linux的目录: mkdir -p /data/fastdfs/tracker
在这里插入图片描述
构建容器
docker run -it -d -p 22122:22122 --name tracker --network=host -v /etc/localtime:/etc/localtime -v /data/fastdfs/tracker:/var/fdfs delron/fastdfs tracker
在这里插入图片描述
查看容器
在这里插入图片描述

构建storage容器(存储服务器,提供容量和备份服务)

创建挂载目录, 将storage容器中的/var/fdfs 文件挂载到自己Linux的目录: mkdir -p /data/fastdfs/storage
在这里插入图片描述
构建容器
docker run -it -d --name storage --network=host -e TRACKER_SERVER=192.168.128.131:22122 -v /data/fastdfs/storage:/var/fdfs -v /etc/localtime:/etc/localtime delron/fastdfs storage
注意: TRACKER_SERVER=本机的ip地址:22122 本机ip地址不要使用127.0.0.1
在这里插入图片描述
查看容器
docker ps
在这里插入图片描述

配置storage端口和Nginx端口(尽量一致)

storage和nginx端口默认为8888(尽量不改)
docker exec -it storage bash
在这里插入图片描述

配置storage端口

进入配置storage文件
vim /etc/fdfs/storage.conf
最后一行
注意: 如果没有vim 就在容器中安装vim: yum install vim
在这里插入图片描述

配置nginx端口

进入配置nginx文件
vim /usr/local/nginx/conf/nginx.conf
在这里插入图片描述
保存退出
退出容器

关闭防火墙(最好是暴露端口)

在这里插入图片描述
或者 开放端口
firewall-cmd --zone=public --add-port=22122/tcp --permanent # 开放22122端口
firewall-cmd --zone=public --add-port=8888/tcp --permanent # 开放8888端口
重启防火墙
firewall-cmd --reload

spring boot+swagger+fdfs实现上传, 下载, 删除等操作

文件目录

在这里插入图片描述

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lqk</groupId>
    <artifactId>filedemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>filedemo</name>
    <description>测试springboot与fastdfs文件服务器整合</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.github.tobato/fastdfs-client -->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.27.2</version>
        </dependency>

<!--        swagger2-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>


        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

server:
  port: 8088

fdfs:
  #连接超时时间
  connect-timeout: 10000
  #交互超时时间限制
  so-timeout: 15000
  #fastdfs的tracker地址
  tracker-list:
    - 192.168.128.131:22122
  # 生成缩略图参数
  thumb-image:
    width: 50
    height: 50
  #存储服务端的地址与端口
  resHost: 192.168.128.131
  storagePort: 8888
  pool:
    #从池中借出的对象的最大数目
    max-total: 20
    #获取连接时的最大等待毫秒数
    max-wait-millis: 10000

spring:
    servlet:
      multipart:
        max-file-size: 50MB
        max-request-size: 50MB

主启动类

package com.lqk.filedemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FiledemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(FiledemoApplication.class, args);
    }

}

AppConfig.class

package com.lqk.filedemo.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 主要是将配置文件的 存储服务端的地址与端口 获取, 注册到容器中以便后面使用
 */
@Component
public class AppConfig {
    @Value("${fdfs.resHost}")
    private String resHost;

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

    public String getResHost() {
        return resHost;
    }

    public void setResHost(String resHost) {
        this.resHost = resHost;
    }

    public String getStoragePort() {
        return storagePort;
    }

    public void setStoragePort(String storagePort) {
        this.storagePort = storagePort;
    }
}

fdfs配置类(DfsConfig.class)

package com.lqk.filedemo.config;


import com.github.tobato.fastdfs.FdfsClientConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(FdfsClientConfig.class) // 导入FastDFS-Client组件
public class DfsConfig {
}

注意: 有的会加上
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
注解, 解决jmx重复注册bean的问题, 我没遇到, 所以没加, 如果报错, 可以加上试试

swagger2的配置文件(SwaggerConfig.class)

package com.lqk.filedemo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;


@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .pathMapping("/")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.lqk.filedemo.controller")) //自己的controller路径, 别忘换了
                .paths(PathSelectors.any())
                .build().apiInfo(new ApiInfoBuilder()
                        .title("springboot整合fastdfs文件服务器")
                        .description("实现文件上传, 下载, 删除....")
                        .version("1.0")
                        .contact(new Contact("lqk", "https://blog.csdn.net/weixin_45286347?spm=1001.2101.3001.5343", "xxx@xx.com")) // 联系人信息
                        .license("The Apache License")
                        .licenseUrl("http://www.baidu.com")
                        .build());
    }

    private ApiInfo apiInfo(){
        Contact contact = new Contact("名字:name", "个人链接:http://xxx.xxx.com/", "邮箱:XXX");
        return new ApiInfo(
                "标题内容", // 标题
                "描述内容", // 描述
                "版本内容:v1.0", // 版本
                "链接:http://terms.service.url/", // 组织链接
                contact, // 联系人信息
                "许可:Apach 2.0 ", // 许可
                "许可链接:XXX", // 许可连接
                new ArrayList<>()// 扩展
        );
    }
}

工具类(FileDfsUtil.class)

package com.lqk.filedemo.util;


import com.github.tobato.fastdfs.domain.fdfs.MetaData;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.lqk.filedemo.config.AppConfig;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Set;

@Component
public class FileDfsUtil {



    @Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private AppConfig appConfig;   // 项目参数配置, 获取存储服务端的地址与端口

    /**
     *	MultipartFile类型的文件上传ַ, 可以上传图片, word文档, pdf, txt等文件
     * @param file
     * @return
     * @throws IOException
     */
    public String uploadFile(MultipartFile file) throws IOException {
        StorePath storePath = storageClient.uploadFile(file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
        return getResAccessUrl(storePath);
    }

    /**
     * 返回文件上传成功后的地址名称ַ
     * @param storePath
     * @return
     */
    private String getResAccessUrl(StorePath storePath) {
        String fileUrl = "http://" + appConfig.getResHost() + ":" + appConfig.getStoragePort() + "/"+storePath.getFullPath();
        return fileUrl;
    }

    /**
     * 文件下载
     */
    public byte[]   downloadFile (String fileUrl) throws IOException{
        String group = fileUrl.substring(0, fileUrl.indexOf("/"));
        String path     = fileUrl.substring(fileUrl.indexOf("/") + 1);
        byte[] bytes = storageClient.downloadFile(group, path,
                new DownloadByteArray());
        return bytes;
    }

    /**
     * 删除文件
     * @param fileUrl
     */
    public void deleteFile(String fileUrl) {
        if (StringUtils.isEmpty(fileUrl)) {
            return;
        }
        try {
            StorePath storePath = StorePath.parseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
        } catch (FdfsUnsupportStorePathException e) {
            System.out.println(e.getMessage());
        }
    }

}

controller层(FileController.class)

package com.lqk.filedemo.controller;

import com.lqk.filedemo.util.FileDfsUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;


@RestController
@Api(tags = "fastdfs文件上传管理")
@RequestMapping("/file")
public class FileController {

    @Autowired
    private FileDfsUtil fileDfsUtil;


    @ApiOperation("上传文件")
    @RequestMapping(value = "/uploadFile", headers="content-type=multipart/form-data", method = RequestMethod.POST)
    public String uploadFile (@ApiParam(required = true, name = "file", value = "请选择一个文件") @RequestParam("file") MultipartFile file){
        String result;
        try {
            String path = fileDfsUtil.uploadFile(file);
            if (!StringUtils.isEmpty(path)){
                result = path ;
                System.out.println(result);
            }else {
                result = "上传失败" ;
            }
        } catch (IOException e) {
            e.printStackTrace();
            result="服务异常";
        }
        return result;
    }

    @ApiOperation("下载文件")
    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    public void downloadFile (@ApiParam(value = "下载的文件 ", required = true) @RequestParam("filePath") String filePath, HttpServletResponse response){
        int lastIndexOf = filePath.lastIndexOf("/");
        String fileName = filePath.substring(lastIndexOf + 1);

        try {
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

            byte[] bytes = fileDfsUtil.downloadFile(filePath);
            InputStream inputStream = new ByteArrayInputStream(bytes);

            byte[] buff = new byte[1024];
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            ServletOutputStream outputStream = response.getOutputStream();
            int read = bufferedInputStream.read(buff);
            while (read != -1) {
                outputStream.write(buff, 0, buff.length);
                outputStream.flush(); //刷新此输出流并强制任何缓冲的输出字节被写出
                read = bufferedInputStream.read(buff);
            }
            outputStream.close(); //关闭此输出流并释放与此流相关联的任何系统资源
            bufferedInputStream.close(); //必须释放,节省资源

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("删除文件")
    @RequestMapping(value = "/deleteFile", method = RequestMethod.DELETE)
    public void deleteFile (@ApiParam(value = "删除文件 ", required = true) @RequestParam("filePath") String filePath){
        fileDfsUtil.deleteFile(filePath);
    }

}

swagger测试

上传文件

http://localhost:8088/swagger-ui.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

查看服务器中上传的文件

路径: /data/fastdfs/storage/data/00/00
在这里插入图片描述

下载文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意: 下载后和上传前的文件名不同

删除文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

原文链接:https://blog.csdn.net/weixin_45286347/article/details/114673119



所属网站分类: 技术文章 > 博客

作者:咿呀咿呀哟

链接:http://www.javaheidong.com/blog/article/114232/0318da5b553ffc74b3c0/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

25 0
收藏该文
已收藏

评论内容:(最多支持255个字符)