springboot使用fastDFS做文件上传的前后端分离案例

1、 搭建fastDFS文件服务器

1)安装fastDFS tracker和storage

2)在storage server上安装nginx

在storage server上安装nginx的目的是对外通过http访问storage server上的文件。

使用nginx的模块FastDFS-nginx-module,它的作用是通过http方式访问storage中的文件,当storage本机没有要

找的文件时向源storage主机代理请求文件。

3)在安装图片服务代理

图片服务代理的作用是负载均衡,根据storage server的负载情况将图片浏览请求均匀的转发到storage server

上。

2、搭建文件管理服务

文件管理服务提供通过http方式上传文件,删除文件、查询文件的功能,管理员通过文件管理服务对文件服务器上

的文件进行管理。

文件管理服务采用Spring Boot开发,文件管理服务通过与fastDFS交互最终将用户上传的文件存储到fastDFS上。

在fastDFS入门程序上继续开发:

package com.shuang.fastdfs.controller;

import com.shuang.fastdfs.FileSystem;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

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

@RestController
@RequestMapping("/filesystem")
public class FileServerController {
    
    

  @Value("${fastdfs.upload_location}")
  private String upload_location;

  @PostMapping("/upload")
  public FileSystem upload(@RequestParam("file") MultipartFile multipartFile) throws IOException {
    
    

    // 将文件先存储在web服务器上(本机),在调用fastDFS的客户端将文件上传到fastDFS服务器
    FileSystem fileSystem = new FileSystem();
    // 得到文件的原始名称
    String originalFilename = multipartFile.getOriginalFilename();
    // 文件扩展名,也就是文件后缀  从“.”的位置开始取
    String extention = originalFilename.substring(originalFilename.lastIndexOf("."));

    String fileNameNew = UUID.randomUUID()+extention;

    // 定义file,使用file存储上传的文件
    File file = new File(upload_location+fileNameNew);
    multipartFile.transferTo(file);
    // 获取新文件上传的物理路径
    String newFilePath = file.getAbsolutePath();

    try {
    
    
      ClientGlobal.initByProperties("config/fastdfs-client.properties");
      System.out.println("network_timeout=" + ClientGlobal.g_network_timeout + "ms");
      System.out.println("charset=" + ClientGlobal.g_charset);

      // 创建tracker客户端
      TrackerClient tc = new TrackerClient();
      TrackerServer ts = tc.getConnection();

      // 场景storage客户端
      StorageServer ss = tc.getStoreStorage(ts);
      StorageClient1 sc1 = new StorageClient1(ts, ss);

      // 文件元信息
      NameValuePair[] meta_list = new NameValuePair[1];
      meta_list[0] = new NameValuePair("fileName",originalFilename);

      // 执行上传,将上传成功的存在再web服务器(本机)上的文件上传到fastDFS
      String fileid;

       // 注意 extention这里设置为null,因为fastDFS会自动帮我们匹配文件拓展名,如果自己在添加一个就会多个点
      fileid = sc1.upload_file1(newFilePath, extention, meta_list);
      fileSystem.setFileId(fileid);
      fileSystem.setFilePath(fileid);
      fileSystem.setFileName(originalFilename);

      // 通过调用service及dao将文件的路径存储到数据库中
      // ...

      System.out.println("Upload local file " + newFilePath + " ok, fileid=" + fileid);
      ts.close();
    } catch (IOException e) {
    
    
      e.printStackTrace();
    } catch (MyException e) {
    
    
      e.printStackTrace();
    }
    return null;
  }
}

yml配置文件

server:
  port: 22100

fastdfs:
  # 文件上传临时目录
  upload_location: D:\\upload\\
fastdfs.connect_timeout_in_seconds = 5

fastdfs.network_timeout_in_seconds = 30

fastdfs.charset = UTF-8

fastdfs.http_anti_steal_token = false

fastdfs.http_secret_key = FastDFS1234567890

fastdfs.http_tracker_http_port = 80

fastdfs.tracker_servers = 192.***.***.7:22122

3、前端

管理员通过管理系统前端上传文件、查询文件、删除文件等操作。

管理系统前端与文件管理服务器通过http交互,这当前流行的前后端分离的架构。

管理系统前端采用当前浏览器的vue.js前端框架实现。

这里注意几个小细节

我们使用了element-ui组件库的文件上传

1、ation是我们文件要上传的路径,也就是我们用springboot搭建的后端接收路径,这是个前后端分离的操作,所以后端要实现跨域可以在springboot的控制器类名前添加@CrossOrigin,或者通过nginx做代理进行映射

2、在el-upload 的内置属性:on-preview 通过回调函数会传一个file,这个file里面有个属性response包含了我们走通过action指定的路径返回结果
在这里插入图片描述
3、使用element-ui的el-upload组件会有一个图片回显的效果,同样是内置属性:on-preview 绑定的回调函数,通过双向数据绑定,在file.response.filePath中绑定路径,路径为远程虚拟机+fastDFS返回的fileId,而且必须在nginx设置了指定fastDFS映射路径才可以访问到图片
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>测试文件上传-图片</title>
</head>
<link rel="stylesheet" href="css/el/index.css"/>
<script src="js/vue/vue.min.js"></script>
<script src="css/el/index.js"></script>
<body>
<div id="app">
  <h1>{
   
   {msg}}</h1>
  <!--ation 是文件接收路径 -->
  <el-upload
          action="http://localhost:22100/filesystem/upload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove">
    <i class="el-icon-plus"></i>
  </el-upload>
  <el-dialog :visible.sync="dialogVisible">
    <img width="100%" :src="dialogImageUrl" alt="">
  </el-dialog>


</div>
</body>
</html>

<script>
    const app = new Vue({
      
      
        el: "#app",
        data: {
      
      
            msg: "1",
            dialogImageUrl: '',
            dialogVisible: false
        },
        methods: {
      
      
            handleRemove(file, fileList) {
      
      
                console.log(file, fileList);
            },
            handlePictureCardPreview(file) {
      
      
                console.log(file)
                this.dialogImageUrl = "http://192.***.***.7/"+file.response.filePath;
                this.dialogVisible = true;
            }
        },
        computed: {
      
      },
        components: {
      
      }
    });
</script>

4、测试

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

猜你喜欢

转载自blog.csdn.net/weixin_46195957/article/details/118770403
今日推荐