Skip to content

Commit 6cb5963

Browse files
author
pedro
committed
feat:重构file extension,添加七牛云上传
1 parent 8c7efb6 commit 6cb5963

8 files changed

Lines changed: 359 additions & 171 deletions

File tree

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@
8484
<version>${hutool.version}</version>
8585
</dependency>
8686

87+
<dependency>
88+
<groupId>com.qiniu</groupId>
89+
<artifactId>qiniu-java-sdk</artifactId>
90+
<version>7.2.28</version>
91+
</dependency>
8792

8893
<dependency>
8994
<groupId>org.springframework.boot</groupId>
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
package io.github.talelin.merak.extensions.file;
2+
3+
import io.github.talelin.autoconfigure.exception.*;
4+
import org.springframework.util.MultiValueMap;
5+
import org.springframework.web.multipart.MultipartFile;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.UUID;
10+
11+
/**
12+
* 文件上传类的基类
13+
* 模版模式
14+
*/
15+
public abstract class AbstractUploader implements Uploader {
16+
17+
private PreHandler preHandler;
18+
19+
public List<File> upload(MultiValueMap<String, MultipartFile> fileMap) {
20+
checkFileMap(fileMap);
21+
// 得到单个文件的大小限制
22+
// 本地存储需先初始化存储文件夹
23+
return handleMultipartFiles(fileMap);
24+
}
25+
26+
public List<File> upload(MultiValueMap<String, MultipartFile> fileMap, PreHandler preHandler) {
27+
this.preHandler = preHandler;
28+
return this.upload(fileMap);
29+
}
30+
31+
protected List<File> handleMultipartFiles(MultiValueMap<String, MultipartFile> fileMap) {
32+
long singleFileLimit = getSingleFileLimit();
33+
List<File> res = new ArrayList<>();
34+
fileMap.keySet().forEach(key -> fileMap.get(key).forEach(file -> {
35+
if (!file.isEmpty()) {
36+
handleOneFile0(res, singleFileLimit, file);
37+
}
38+
}));
39+
return res;
40+
}
41+
42+
private void handleOneFile0(List<File> res, long singleFileLimit, MultipartFile file) {
43+
byte[] bytes = getFileBytes(file);
44+
String[] include = getFileProperties().getInclude();
45+
String[] exclude = getFileProperties().getExclude();
46+
String ext = checkOneFile(include, exclude, singleFileLimit, file.getOriginalFilename(), bytes.length);
47+
String newFilename = getNewFilename(ext);
48+
String storePath = getStorePath(newFilename);
49+
// 生成文件的md5值
50+
String md5 = FileUtil.getFileMD5(bytes);
51+
File fileData = File.builder().
52+
name(newFilename).
53+
md5(md5).
54+
path(storePath).
55+
size(bytes.length).
56+
type(getFileType()).
57+
extension(ext).
58+
build();
59+
// 如果预处理器不为空,且处理结果为false,直接返回, 否则处理
60+
if (preHandler != null && !preHandler.handle(fileData))
61+
return;
62+
boolean ok = handleOneFile(bytes, newFilename);
63+
if (ok) {
64+
res.add(fileData);
65+
}
66+
}
67+
68+
private long getSingleFileLimit() {
69+
String singleLimit = getFileProperties().getSingleLimit();
70+
return FileUtil.parseSize(singleLimit);
71+
}
72+
73+
/**
74+
* 得到文件配置
75+
*
76+
* @return 文件配置
77+
*/
78+
protected abstract FileProperties getFileProperties();
79+
80+
/**
81+
* 处理一个文件
82+
*/
83+
protected abstract boolean handleOneFile(byte[] bytes, String newFilename);
84+
85+
/**
86+
* 返回文件路径
87+
*
88+
* @param newFilename 文件名
89+
* @return 文件路径
90+
*/
91+
protected abstract String getStorePath(String newFilename);
92+
93+
/**
94+
* 返回文件存储位置类型
95+
*
96+
* @return LOCAL | REMOTE
97+
*/
98+
protected abstract String getFileType();
99+
100+
/**
101+
* 获得新文件的名称
102+
*
103+
* @param ext 文件后缀
104+
* @return 新名称
105+
*/
106+
protected String getNewFilename(String ext) {
107+
String uuid = UUID.randomUUID().toString().replace("-", "");
108+
return uuid + ext;
109+
}
110+
111+
/**
112+
* 检查文件
113+
*/
114+
protected void checkFileMap(MultiValueMap<String, MultipartFile> fileMap) {
115+
if (fileMap.isEmpty()) {
116+
throw new NotFoundException("file not found", 10026);
117+
}
118+
int nums = getFileProperties().getNums();
119+
if (fileMap.size() > nums) {
120+
throw new FileTooManyException("too many files, amount of files must less than" + nums, 10180);
121+
}
122+
}
123+
124+
/**
125+
* 获得文件的字节
126+
*
127+
* @param file 文件
128+
* @return 字节
129+
*/
130+
protected byte[] getFileBytes(MultipartFile file) {
131+
byte[] bytes;
132+
try {
133+
bytes = file.getBytes();
134+
} catch (Exception e) {
135+
throw new FailedException("read file date failed", 10190);
136+
}
137+
return bytes;
138+
}
139+
140+
/**
141+
* 单个文件检查
142+
*
143+
* @param singleFileLimit 单个文件大小限制
144+
* @param originName 文件原始名称
145+
* @param length 文件大小
146+
* @return 文件的扩展名,例如: .jpg
147+
*/
148+
protected String checkOneFile(String[] include, String[] exclude, long singleFileLimit, String originName, int length) {
149+
// 写到了本地
150+
String ext = FileUtil.getFileExt(originName);
151+
// 检测扩展
152+
if (!this.checkExt(include, exclude, ext)) {
153+
throw new FileExtensionException(ext + "文件类型不支持");
154+
}
155+
// 检测单个大小
156+
if (length > singleFileLimit) {
157+
throw new FileTooLargeException(originName + "文件不能超过" + singleFileLimit);
158+
}
159+
return ext;
160+
}
161+
162+
/**
163+
* 检查文件后缀
164+
*
165+
* @param ext 后缀名
166+
* @return 是否通过
167+
*/
168+
protected boolean checkExt(String[] include, String[] exclude, String ext) {
169+
int inLen = include == null ? 0 : include.length;
170+
int exLen = exclude == null ? 0 : exclude.length;
171+
// 如果两者都有取 include,有一者则用一者
172+
if (inLen > 0 && exLen > 0) {
173+
return this.findInInclude(include, ext);
174+
} else if (inLen > 0) {
175+
// 有include,无exclude
176+
return this.findInInclude(include, ext);
177+
} else if (exLen > 0) {
178+
// 有exclude,无include
179+
return this.findInExclude(exclude, ext);
180+
} else {
181+
// 二者都没有
182+
return true;
183+
}
184+
}
185+
186+
protected boolean findInInclude(String[] include, String ext) {
187+
for (String s : include) {
188+
if (s.equals(ext)) {
189+
return true;
190+
}
191+
}
192+
return false;
193+
}
194+
195+
protected boolean findInExclude(String[] exclude, String ext) {
196+
for (String s : exclude) {
197+
if (s.equals(ext)) {
198+
return true;
199+
}
200+
}
201+
return false;
202+
}
203+
}

src/main/java/io/github/talelin/merak/extensions/file/FileProperties.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,24 @@ public class FileProperties {
1111

1212
private static final String[] DEFAULT_EMPTY_ARRAY = new String[0];
1313

14-
private String dir = "/assets";
14+
private String storeDir = "/assets";
1515

1616
private String singleLimit = "2MB";
1717

1818
private Integer nums = 10;
1919

20+
private String domain;
21+
2022
private String[] exclude = DEFAULT_EMPTY_ARRAY;
2123

2224
private String[] include = DEFAULT_EMPTY_ARRAY;
2325

24-
public String getDir() {
25-
return dir;
26+
public String getStoreDir() {
27+
return storeDir;
2628
}
2729

28-
public void setDir(String dir) {
29-
this.dir = dir;
30+
public void setStoreDir(String storeDir) {
31+
this.storeDir = storeDir;
3032
}
3133

3234
public String getSingleLimit() {
@@ -60,4 +62,12 @@ public String[] getInclude() {
6062
public void setInclude(String[] include) {
6163
this.include = include;
6264
}
65+
66+
public String getDomain() {
67+
return domain;
68+
}
69+
70+
public void setDomain(String domain) {
71+
this.domain = domain;
72+
}
6373
}

0 commit comments

Comments
 (0)