文件上传可能会遇到重名的文件那么遇到重名的文件后面上传的会把前面上传同名的文件覆盖掉,这里解决了重名文件覆盖的问题,多个同名文件上传做了后缀+1处理
1,请求实例
apifox请求实例
2,controller
/**
* 文件上传
* @param: moduleName 模块名
* @param: recordId 记录id
* @param: fileType 文件类型
*/
@PostMapping("/upload")
public Map upload(MultipartFile[] files, @RequestParam(required = false) String moduleName,
@RequestParam(required = false) String recordId,@RequestParam(required = false) String fileType, HttpServletRequest request) throws IOException {
return fileUploadBiz.upload(files,moduleName,recordId,fileType,request);
}
3,service
service几行代码此处省略
4,impl
private final String[] arrSuffix = {"jpg", "jpeg", "jpe", "bmp", "gif", "png", "svg", "rar", "zip", "7z", "pdm", "doc", "xls", "ppt", "tif", "txt", "chm", "docx", "xlsx", "pptx", "pdf", "vsd", "mpp", "jpg", "jpeg", "jpe", "bmp", "gif", "png", "avi", "asx", "asf", "mpg", "wmv", "3gp", "mp3", "mp4", "mov", "flv", "wmv9", "rm", "rmvb", "et", "wps", "dps", "pmp", "bdc", "ceb", "wmf", "ofd", "ttf", "woff", "woff2", "ttc", "fon", "font", "otf", "eot"};
@Value("${file.path}")
private String filePath;
/**
* 文件上传
* @param: files
* @param: moduleName 模块名
* @param: recordId 记录id
* @param: fileType 文件类型
* @param: request
* @return:
*/
public Map upload(MultipartFile[] files, String moduleName, String recordId, String fileType, HttpServletRequest request) throws IOException {
Map retMap = new HashMap();
//定义返回地址
String fileDownloadUrl = "";
String fileName = "";
for (MultipartFile file : files) {
// 获取文件名
fileName = file.getOriginalFilename();
//获取后缀
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
//判断上传文件是否有文件类型
if (StringUtils.isEmpty(suffix)) {
throw new InspactDataException(InspactDataResultEnum.FILE_TYPE_EXCEEDED);
}
//判断上传文件类型是否是指定类型
boolean isContains = Arrays.asList(arrSuffix).contains(suffix);
if (isContains == false) {
throw new InspactDataException(InspactDataResultEnum.FILE_TYPE_EXCEEDED);
}
//文件上传名字重复后缀+1 获得+1后的文件名
String newFileName = checkFileName(filePath + (moduleName!=null?moduleName+ "/":"") + (recordId!=null?recordId+ "/":"") + (fileType!=null?fileType+ "/":"") , fileName);
// 拼接后的文件上传地址
fileName = "/"+(moduleName!=null?moduleName+ "/":"") + (recordId!=null?recordId+ "/":"") + (fileType!=null?fileType+ "/":"") + newFileName;
//创建文件
File dest = new File(filePath +fileName);
//判断文件父目录是否存在
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs(); //这里因为创建的是多级目录,所以需要使用mkdirs()方法。使用mkdir()方法则文件夹创建不成功,会报找不到路径错误。
}
try {
//将文件内容写入创建的文件中
file.transferTo(dest);
//多个文件以逗号相隔
if (fileDownloadUrl == "") {
fileDownloadUrl = fileName;
} else {
fileDownloadUrl = fileDownloadUrl + ","+ fileName;
}
} catch (IOException e) {
log.error("上传文件失败" + e.getMessage());
throw new GenericException("上传文件失败" + e.getMessage());
}
}
retMap.put("url", fileDownloadUrl);
//返回Url地址,多个文件以逗号分隔 前端下载需要拼接完整url:test/111/aaa/微信图片_20220922174306.jpg
return retMap;
}
5,文件相同文件名后缀+1方法
/**
* 获取文件夹中相同文件名的文件个数
*
* @param filePath
* @param fileName
* @return
*/
private int getFileMax(String filePath, String fileName) {
File file = new File(filePath);
File[] files;
int number = 0;
if (file.isDirectory()) {
files = file.listFiles();
for (int i = 0; i < files.length; i++) {
File f = files[i];
if (f.isFile()
&& (f.getName().substring(0, f.getName().lastIndexOf("."))
.contains(fileName.substring(0, fileName.lastIndexOf(".")))
&& f.getName().substring(f.getName().lastIndexOf("."))
.equals(fileName.substring(fileName.lastIndexOf("."))))) {
number = number + 1;
}
}
}
return number;
}
/**
* 校验文件名称相同,若相同后缀(+n)
*
* @param filePath 文件路径
* @param fileName 文件名称
* @return 新文件名称
*/
private String checkFileName(String filePath, String fileName) {
int fileMax = getFileMax(filePath, fileName);
//重复的文件名
StringBuilder newFileName = new StringBuilder();
if (fileMax > 0) {
newFileName.append(fileName.substring(0, fileName.lastIndexOf("."))).
append("(" + fileMax + ")").append(fileName.substring(fileName.lastIndexOf(".")));
} else {
newFileName.append(fileName);
}
return newFileName.toString();
}