Skip to content

Commit 5cfc30b

Browse files
committed
feat: 添加通用上传下载API
1 parent 1f6560c commit 5cfc30b

5 files changed

Lines changed: 193 additions & 1 deletion

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package top.cadecode.uniboot.controller;
2+
3+
import cn.hutool.core.io.FileUtil;
4+
import cn.hutool.extra.servlet.ServletUtil;
5+
import io.swagger.annotations.Api;
6+
import io.swagger.annotations.ApiOperation;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.PostMapping;
11+
import org.springframework.web.bind.annotation.RequestPart;
12+
import org.springframework.web.bind.annotation.RestController;
13+
import org.springframework.web.multipart.MultipartFile;
14+
import top.cadecode.uniboot.common.annotation.ApiFormat;
15+
import top.cadecode.uniboot.common.enums.error.FrameErrorEnum;
16+
import top.cadecode.uniboot.common.exception.UniException;
17+
import top.cadecode.uniboot.common.util.AssertUtil;
18+
import top.cadecode.uniboot.framework.manager.FileUploadManager;
19+
20+
import javax.servlet.http.HttpServletRequest;
21+
import javax.servlet.http.HttpServletResponse;
22+
import java.io.File;
23+
import java.io.IOException;
24+
25+
/**
26+
* 通用API
27+
*
28+
* @author Cade Li
29+
* @since 2023/4/9
30+
*/
31+
@ApiFormat
32+
@Slf4j
33+
@RequiredArgsConstructor
34+
@Api(tags = "通用API")
35+
@RestController
36+
public class CommonController {
37+
38+
@ApiOperation("上传文件")
39+
@PostMapping("common/upload")
40+
public boolean upload(@RequestPart("file") MultipartFile file) {
41+
String originalFilename = file.getOriginalFilename();
42+
boolean checked = FileUploadManager.checkAllowedExtension(originalFilename);
43+
AssertUtil.isFalse(checked, FrameErrorEnum.EXTENSION_NOT_ALLOWED, originalFilename + "不被允许");
44+
String renamedFileName = FileUploadManager.renameByUUID(originalFilename);
45+
String targetFilePath = FileUploadManager.uploadPath() + renamedFileName;
46+
try {
47+
File targetFile = FileUtil.file(targetFilePath);
48+
FileUtil.mkParentDirs(targetFile);
49+
file.transferTo(targetFile);
50+
} catch (IOException e) {
51+
throw UniException.of(FrameErrorEnum.UPLOAD_FILE_FAIL, e, originalFilename + "上传失败");
52+
}
53+
return true;
54+
}
55+
56+
@ApiOperation("上传多文件")
57+
@PostMapping("common/upload_files")
58+
public int uploadFiles(@RequestPart("files") MultipartFile[] files) {
59+
int res = 0;
60+
for (MultipartFile file : files) {
61+
upload(file);
62+
res++;
63+
}
64+
return res;
65+
}
66+
67+
@ApiOperation("下载文件")
68+
@GetMapping(FileUploadManager.DEFAULT_DOWNLOAD_API)
69+
public void download(HttpServletRequest request, HttpServletResponse response, String fileName) throws IOException {
70+
boolean checked = FileUploadManager.checkAllowedExtension(fileName);
71+
AssertUtil.isFalse(checked, FrameErrorEnum.EXTENSION_NOT_ALLOWED, fileName + "不被允许");
72+
// 写文件流
73+
String targetFilePath = FileUploadManager.downloadPath() + fileName;
74+
boolean exist = FileUtil.exist(targetFilePath);
75+
AssertUtil.isFalse(exist, FrameErrorEnum.FILE_NOT_FOUND, fileName + "不存在");
76+
ServletUtil.write(response, new File(targetFilePath));
77+
}
78+
79+
@ApiOperation("下载临时文件")
80+
@GetMapping(FileUploadManager.DEFAULT_DOWNLOAD_TEMP_API)
81+
public void downloadTemp(HttpServletRequest request, HttpServletResponse response, String fileName) throws IOException {
82+
download(request, response, fileName);
83+
String targetFilePath = FileUploadManager.downloadPath() + fileName;
84+
FileUtil.del(targetFilePath);
85+
}
86+
87+
}

application/src/main/resources/application-dev.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ uni-boot:
2929
version: 0.0.1
3030
swagger-on: true
3131
dynamic-ds-on: false
32+
file-base-path: D:/uniboot/file/temp/
3233
# swagger 配置
3334
swagger:
3435
title: Swagger 在线文档
@@ -46,4 +47,4 @@ uni-boot:
4647
header: token
4748
expiration: 86400
4849
secret: 12345678123456781234567812345678
49-
ignore-urls: /auth/**,/druid/**,/actuator/**,/demo/**
50+
ignore-urls: /auth/**,/druid/**,/actuator/**,/demo/**,/common/download**

common/src/main/java/top/cadecode/uniboot/common/enums/error/FrameErrorEnum.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public int getStatus() {
4949
return ApiStatus.TOO_MANY_REQUESTS;
5050
}
5151
},
52+
EXTENSION_NOT_ALLOWED(6, "上传或下载文件的类型不被允许"),
53+
UPLOAD_FILE_FAIL(7, "上传文件失败"),
54+
FILE_NOT_FOUND(8, "文件未找到"),
5255
;
5356

5457
private final String code;

framework/src/main/java/top/cadecode/uniboot/framework/config/UniBootConfig.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import org.springframework.boot.context.properties.ConfigurationProperties;
77
import org.springframework.context.annotation.Configuration;
88

9+
import java.util.List;
10+
911
/**
1012
* uni-boot-admin 主配置类,维护一些功能开关和全局变量
1113
*
@@ -38,4 +40,15 @@ public class UniBootConfig {
3840
* 是否开启动态数据源配置
3941
*/
4042
private boolean dynamicDsOn;
43+
44+
/**
45+
* 文件基本路径,以/结尾
46+
*/
47+
private String fileBasePath;
48+
49+
/**
50+
* 可上传下载的扩展文件类型
51+
*/
52+
private List<String> allowedFileExtensions;
53+
4154
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package top.cadecode.uniboot.framework.manager;
2+
3+
import cn.hutool.core.collection.CollUtil;
4+
import cn.hutool.core.io.file.FileNameUtil;
5+
import cn.hutool.core.lang.UUID;
6+
import cn.hutool.core.util.StrUtil;
7+
import lombok.RequiredArgsConstructor;
8+
import lombok.extern.slf4j.Slf4j;
9+
import org.springframework.beans.factory.InitializingBean;
10+
import org.springframework.stereotype.Component;
11+
import top.cadecode.uniboot.framework.config.UniBootConfig;
12+
13+
import java.util.Set;
14+
15+
/**
16+
* 文件上传及下载工具类
17+
*
18+
* @author Cade Li
19+
* @since 2023/4/10
20+
*/
21+
@Slf4j
22+
@RequiredArgsConstructor
23+
@Component
24+
public class FileUploadManager implements InitializingBean {
25+
26+
private final UniBootConfig uniBootConfig;
27+
28+
public static final String DEFAULT_FILE_BASE_PATH = "/uniboot/file/temp/";
29+
public static final String DEFAULT_DOWNLOAD_API = "/common/download";
30+
public static final String DEFAULT_DOWNLOAD_TEMP_API = "/common/download_temp";
31+
private static String UPLOAD_PATH;
32+
private static String DOWNLOAD_PATH;
33+
private static final Set<String> ALLOWED_EXTENSIONS = CollUtil.newHashSet(
34+
// image
35+
"bmp", "gif", "jpg", "jpeg", "png",
36+
// text
37+
"txt", "py", "java", "js",
38+
// office
39+
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", "pdf",
40+
// zip
41+
"rar", "zip", "gz", "bz2",
42+
// video
43+
"mp3", "mp4", "avi", "rmvb"
44+
);
45+
46+
public static String uploadPath() {
47+
return UPLOAD_PATH;
48+
}
49+
50+
public static String downloadPath() {
51+
return DOWNLOAD_PATH;
52+
}
53+
54+
public static String downloadUrl(String fileName) {
55+
return DEFAULT_DOWNLOAD_API + "?fileName=" + fileName;
56+
}
57+
58+
public static String downloadTempUrl(String fileName) {
59+
return DEFAULT_DOWNLOAD_TEMP_API + "?fileName=" + fileName;
60+
}
61+
62+
public static boolean checkAllowedExtension(String fileName) {
63+
String suffix = FileNameUtil.getSuffix(fileName);
64+
return ALLOWED_EXTENSIONS.contains(suffix);
65+
}
66+
67+
public static String renameByUUID(String fileName) {
68+
return UUID.fastUUID().toString(true) + "_" + fileName;
69+
}
70+
71+
public static String renameByTime(String fileName) {
72+
return System.currentTimeMillis() + "_" + fileName;
73+
}
74+
75+
@Override
76+
public void afterPropertiesSet() {
77+
if (StrUtil.isEmpty(uniBootConfig.getFileBasePath())) {
78+
uniBootConfig.setFileBasePath(DEFAULT_FILE_BASE_PATH);
79+
log.info("Set uniboot config file base path to default {}", DEFAULT_FILE_BASE_PATH);
80+
}
81+
UPLOAD_PATH = uniBootConfig.getFileBasePath() + "upload/";
82+
DOWNLOAD_PATH = uniBootConfig.getFileBasePath() + "download/";
83+
// 加入额外配置的后缀
84+
if (CollUtil.isNotEmpty(uniBootConfig.getAllowedFileExtensions())) {
85+
ALLOWED_EXTENSIONS.addAll(uniBootConfig.getAllowedFileExtensions());
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)