§ 本文目标
本章将介绍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
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
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
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
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
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
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
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
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
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