§ 本文目标

本章将介绍yusp-common-file组件的使用,yusp-file微服务API常用接口

§ 练习场景

使用组件,实现文件上传下载;熟悉并使用yufp-file微服务API常用接口

前提:

  • 基于微服务工程创建章节创建的工程开发

§ 操作步骤

§ 配置

§ pom引入依赖

<dependency>
     <groupId>cn.com.yusys.yusp</groupId>
     <artifactId>yusp-common-file</artifactId>
</dependency>
1
2
3
4

可扩展接口类

cn.com.yusys.yusp.commons.file.ClientFactory #文件上传下载工厂

cn.com.yusys.yusp.commons.file.FileManagementClient #文件操作客户端

§ 应用配置

该包默认提供了:本地、FASTDFS两个存储方式的实现,通过配置文件可以进行快速切换:

fastdfs模式

fastdfs application config

application:
    file:
                    enabled: true
        file-storage-type: fastdfs  
        fastdfs-track-ip: 192.168.251.151:22122
1
2
3
4
5

本地文件模式

local application config

application:
    file:
                    enabled: true
        file-storage-type: localdisk   
        local-disk-path: D:/localDisk # localdisk setting
1
2
3
4
5

配置信息由FileManageAutoConfiguration自动加载

开启文件上传下载过滤器及允许上传下载的文件类型白名单

local application config

application:
    filter: 
        fileupload: 
            enabled: true #过滤器-防止恶意文件上传
            access-file-type: docx,doc,xlsx,xls,txt,jpg,png,pdf,zip,rar #可上传的白名单文件类型,如不配置默认允许的白名单文件类型为:docx,doc,xlsx,xls,txt,jpg,png,pdf,zip,rar
1
2
3
4
5

§ 文件上传下载开发

常用方法

//bean注入
@Autowired
ClientFactory clientFactory;
 
//初始化连接
FileManagementCilent fileClient = clientFactory.getFileManagementCilent();
fileClient .initConnection();
 
 
//上传本地文件
File file = new File("C:\\Users\\figue\\Desktop\\1208172911.png");
String fileId = fileClient .uploadFile(file);
System.out.println(fileId);
 
 
//上传文件,含基本信息
Map<String, String> fileInfo = new HashMap<String, String>();
fileInfo.put("fileName", file.getName());
fileInfo.put("size", file.length() + "");
String fileId2 = fileClient .uploadFile(file, fileInfo);
System.out.println(fileId2);
 
 
//更新文件基本信息
Map<String, String> fileInfo2 = new HashMap<String, String>();
fileInfo2.put("fileName", file.getName()+"ggggg");
fileInfo2.put("fileNamedd", file.getName()+"gggggddd");
fileInfo2.put("size", file.length() + "");
fileClient .updateFileInfo(fileId2, fileInfo2);
 
 
//获取文件基本信息,本地磁盘存储方式不支持此方法
fileClient .getFileInfo(fileId);
 
//删除文件
fileClient .deleteFile(fileId);
 
//下载文件
fileClient.downloadFile(fileId);
 
//关闭连接
fileClient .closeConnection();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

开发示例

应用资源Resource层

package cn.com.yusys.yusp.web.rest;
import java.io.OutputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import cn.com.yusys.yusp.commons.util.StringUtil;
import cn.com.yusys.yusp.commons.web.rest.dto.ResultDto;
import cn.com.yusys.yusp.service.FileService;
@RestController
@RequestMapping("/api/file")
public class FileResource {
          @Autowired
          private FileService fileService;
          
           /**
     * 文件上传.
     * 
     * @param file 本地文件
     * @param fileName 文件名称
     * @return 文件基本信息
     */
          @PostMapping("/uploadfile")
          public ResultDto<Map<String, String>> uploadFile(MultipartFile file, String fileName)
                               throws IOException {
                    // 当未单独传递文件名称时,取文件name,可能中文乱码
                    if (StringUtil.isEmpty(fileName)) {
                               fileName = file.getOriginalFilename();
                    }
                    fileName = URLDecoder.decode(fileName, "UTF-8");
                    Map<String, String> map = fileService.uploadFile(file, fileName);
                    return new ResultDto<Map<String, String>>(map);
          }
          
           /**
     * 更新文件信息.
     * 
     * @param fileId 文件唯一标识;形如:group1/M00/00/02/wKjGhloviIeAHYVMAAAQNZs2s_4791.png
     * @return 文件基本信息
     */
          @PostMapping("/updatefileinfo")
          public ResultDto<Map<String,String>> updateFileInfo(String fileId){
                    Map<String, String> map = fileService.updateFileInfo(fileId);
                    return new ResultDto<Map<String, String>>(map);
          }
          
           /**
     * 删除文件.
     * 
     * @param fileId 文件唯一标识;形如:group1/M00/00/02/wKjGhloviIeAHYVMAAAQNZs2s_4791.png
     * @return 0 成功;非0失败,包含文件不存在
     */
          @PostMapping("/deletefile")
          public ResultDto<Integer> deleteFile(String fileId){
                    int result = fileService.deleteFile(fileId);
                    return new ResultDto<Integer>(result);
          }
          
           /**
     * 下载文件.
     * 
     * @param fileId 文件唯一标识;形如:group1/M00/00/02/wKjGhloviIeAHYVMAAAQNZs2s_4791.png
     * @param response 写文件的响应流
     */
          @GetMapping("/downloadfile")
          public void downloadFile(String fileId,HttpServletResponse response) {
                    String fileName = fileId.substring(fileId.lastIndexOf("/") + 1);
                    response.setHeader("content-type", "application/octet-stream");
                    response.setContentType("application/octet-stream");
                    response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
                    OutputStream os = null;
                    try {
                               os = response.getOutputStream();
                               // 下载
                               byte[] content = fileService.downloadFile(fileId);
                               os.write(content);
                               os.flush();
                    } catch (Exception e) {
                               e.printStackTrace();
                    } 
          }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

业务逻辑Service层

package cn.com.yusys.yusp.service;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import cn.com.yusys.yusp.commons.file.ClientFactory;
import cn.com.yusys.yusp.commons.file.FileManagementClient;
@Service
public class FileService {
          //bean注入
          @Autowired
          ClientFactory clientFactory;
          
           /**
     * 文件上传.
     * 
     * @param file 文件
     * @param fileName 文件名称
     * @return 文件基本信息
     */
          public Map<String, String> uploadFile(MultipartFile file, String fileName) throws IOException{
                    // 初始化连接
                    FileManagementClient fileClient = clientFactory.getFileManagementClient();
                    fileClient.initConnection();
 
                    String fileNameExt = fileName.substring(fileName.lastIndexOf(".") + 1);
                    
                    // 上传文件,不含基本信息
                    String fileId = fileClient.uploadFile(file.getBytes(), fileNameExt, null);
                    System.out.println(fileId);
 
                    // 上传文件,含基本信息
                    Map<String, String> fileInfo = new HashMap<String, String>();
                    fileInfo.put("fileName", fileName);
                    fileInfo.put("size", file.getSize() + "");
                    String fileId2 = fileClient.uploadFile(file.getBytes(), fileNameExt, fileInfo);
                    fileInfo.put("fileId", fileId2);
                    
                    // 关闭连接
                    fileClient.closeConnection();
                    return fileInfo;
          }
          
           /**
     * 更新文件信息.
     * 
     * @param fileId 文件唯一标识;形如:group1/M00/00/02/wKjGhloviIeAHYVMAAAQNZs2s_4791.png
     * @return 文件基本信息
     */
          public Map<String, String> updateFileInfo(String fileId) {
                    // 初始化连接
                    FileManagementClient fileClient = clientFactory.getFileManagementClient();
                    fileClient.initConnection();
                    // 获取文件基本信息,本地磁盘存储方式不支持此方法
                    Map<String, String> fileInfo = new HashMap<String, String>();
                    fileInfo = fileClient.getFileInfo(fileId);
                    // 更新文件基本信息
                    fileInfo.put("fileName", "ggggg");
                    fileInfo.put("fileNamedd", "gggggddd");
                    fileClient.updateFileInfo(fileId, fileInfo);
                    // 关闭连接
                    fileClient.closeConnection();
                    return fileInfo;
          }
          
           /**
     * 删除文件.
     * 
     * @param fileId 文件唯一标识;形如:group1/M00/00/02/wKjGhloviIeAHYVMAAAQNZs2s_4791.png
     * @return 0 成功;非0失败,包含文件不存在
     */
          public int deleteFile(String fileId) {
                    // 初始化连接
                    FileManagementClient fileClient = clientFactory.getFileManagementClient();
                    fileClient.initConnection();
                    // 删除文件
                    int result = fileClient.deleteFile(fileId);
                    // 关闭连接
                    fileClient.closeConnection();
                    return result;
          }
          
           /**
     * 下载文件.
     * 
     * @param fileId 文件唯一标识;形如:group1/M00/00/02/wKjGhloviIeAHYVMAAAQNZs2s_4791.png
     * @return 文件字节数组
     */
          public byte[] downloadFile(String fileId) {
                    // 初始化连接
                    FileManagementClient fileClient = clientFactory.getFileManagementClient();
                    fileClient.initConnection();
                    // 下载文件
                    byte[] content = fileClient.downloadFile(fileId);
                    
                    // 关闭连接
                    fileClient.closeConnection();
                    return content;
          }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

§ yusp-file常用接口

基于yusp-common-file组件,平台进行了微服务封装,提供常用的API接口,供前端使用

§ 上传

POST请求

/api/file/provider/uploadfile

§ 下载

get请求

/api/file/provider/downloadfile

示例:/api/file/provider/downloadfile?fileId=fileId

支持批量操作,fileId以逗号分隔

§ 删除

get请求

/api/file/provider/deleteFile

示例:/api/file/provider/deleteFile?fileId=fileId

支持批量操作,fileId以逗号分隔

§ 前端示例

fileop.html

<!-- 文件上传下载示例 -->
<div>
<br/>
<div style="color:red">
<h2> 文件操作示例:上传、下载、删除</h2>
</div>
<el-upload style="display:inline-block" 
:show-file-list="false" :multiple="multiple"
:file-list="fileList" :headers="headers"
:action="action" :data="data"
:on-success="onSuccess" :on-error="onError"
:on-change="onChange"> <el-button>上传</el-button>
</el-upload>
<el-button @click="downloadFile">下载</el-button>
<el-button @click="deleteFile">删除</el-button>
<el-table-x ref="accessTable" :checkbox="true" :data-url="dataUrl" :table-columns="columns"></el-table-x>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

fileop.js

define(function (require, exports) {
  // page加载完成后调用ready方法
  exports.ready = function (hashCode, data, cite) {
    yufp.custom.vue({
      el: cite.el,
      data: function () {
        return {
          height: yufp.custom.viewSize().height,
 
          // 上传url
          uploadAction: backend.gatewayService + backend.fileService + '/api/file/provider/uploadfile',
          downloadUrl: backend.gatewayService + backend.fileService + '/api/file/provider/download?fileId=',
          dataUrl: backend.fileService + '/api/file/provider/',
          // 额外请求参数
          data: {
            busNo: 'xxxxxxx'
          },
          // 是否支持同时选多个文件
          multiple: true,
          tableColumns: Array,
          // 指定文件地址,删除/下载物理文件时需要该参数
          fileAddress: 'filePath',
          headers: {
            'Authorization': 'Bearer ' + yufp.service.getToken()
          },
          fileList: [],
          columns: [{
            label: '文件名称',
            prop: 'fileName'
          }, {
            label: '文件路径',
            prop: 'filePath'
          }, {
            label: '文件大小 /kb',
            prop: 'fileSize'
          }, {
            label: '上传时间',
            prop: 'uploadTime'
          }]
        };
      },
      computed: {
        action: function () {
          var me = this;
          return yufp.service.getUrl({url: me.uploadAction});
        }
      },
      methods: {
        // 文件上传成功处理逻辑
        onSuccess: function () {
          // 刷新table
          this.queryFn();
        },
        onError: function () {
          this.$message('文件上传失败!', '提示');
        },
        onChange: function (file, fileList) {
          // 添加文件时,把文件名称单独列出来
          this.data.fileName = file.name;
        },
        // 文件下载
        downloadFile: function () {
          var _data = this.$refs.accessTable.selections;
          if (_data == null || _data.length == 0) {
            this.$message('请至少选择一条数据', '提示');
            return;
          }
          var fileIds = '';
          for (var i = 0; i < _data.length; i++) {
            if (i == 0) {
              fileIds += _data[i][this.fileAddress];
            } else {
              fileIds += ',' + _data[i][this.fileAddress];
            }
          }
          yufp.util.download(this.downloadUrl + fileIds);
        },
        // 文件删除
        deleteFile: function () {
          var me = this;
          // 删除文件
          var _data = this.$refs.accessTable.selections;
          if (_data == null || _data.length == 0) {
            this.$message('请至少选择一条数据', '提示');
            return;
          }
 
          var ids = '', fileIds = '';
          for (var i = 0; i < _data.length; i++) {
            if (i == 0) {
              ids += _data[i].fileId;
              fileIds += _data[i][this.fileAddress];
            } else {
              ids += ',' + _data[i].fileId;
              fileIds += ',' + _data[i][this.fileAddress];
            }
          }
          yufp.service.request({
            url: backend.fileService + '/api/file/provider/deleteFile',
            method: 'get',
            data: {
              fileId: fileIds
            },
            callback: function (code, message, res) {
              if (code == 0) {
                me.$message('删除成功!', '提示');
                me.queryFn();
              }
            }
          });
        },
        queryFn: function () {
          this.$refs.accessTable.remoteData();
        }
      }
    });
  };
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
最后更新于: 4/28/2022, 4:58:56 PM