<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Upload</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/webuploader/0.1.1/webuploader.min.js"></script>
</head>
<body>
<div id="uploader">
<div class="btns">
<div id="picker">选择文件</div>
</div>
</div>
<script>
var uploader = WebUploader.create({
auto: true,
fileVal: "file",
swf: 'https://cdn.bootcdn.net/ajax/libs/webuploader/0.1.1/Uploader.swf',
server: 'http://localhost:8080/system/file/chunk',
chunked: true,
chunkSize: 10 * 1024 * 1024,
duplicate: true,
chunkRetry: 3,
pick: '#picker',
method: 'POST',
fileNumLimit: 1,
fileSizeLimit: 100 * 1024 * 1024,
fileSingleSizeLimit: 50 * 1024 * 1024,
});
uploader.on('uploadComplete', function (file) {
console.log('upload complete');
console.log(file);
$.ajax({
url: 'http://localhost:8080/system/file/merge',
data: {
name: file.name
},
type: 'POST',
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
}
});
});
</script>
</body>
</html>
package com.question.controller;
import com.question.common.exception.ServerException;
import com.question.common.result.ResData;
import com.question.common.result.ResEnum;
import com.question.common.result.WangEditorImage;
import com.question.common.result.WangEditorVideo;
import com.question.utils.upload.FileUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/system/file")
public class FileController {
@Value("${file.local}")
private boolean local;
@Value("${file.path}")
private String path;
@PostMapping("/chunk")
public ResData<?> uploadChunk(@RequestParam("file") MultipartFile file,
Integer chunk,
Integer chunks,
@RequestParam("name") String name, HttpServletRequest request) {
String url = "";
if (local && chunks!= null && chunks > 1) {
url = FileUtils.uploadChunkFileToLocal(file, name, chunk, chunks, path, request);
} else if (local) {
url = FileUtils.uploadFileToLocal(file, request, path);
} else {
}
return ResData.success(ResEnum.SUCCESS.getCode(), "文件分片上传成功", url);
}
@PostMapping("/merge")
public ResData<?> mergeChunks(@RequestParam("name") String name,
HttpServletRequest request) {
String url =FileUtils.mergeChunks(name,path,request);
return ResData.success(ResEnum.SUCCESS.getCode(), "文件分片上传成功", url);
}
@PostMapping("/upload")
public ResData<?> upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws ServerException {
String url = null;
if (local) {
url = FileUtils.uploadFileToLocal(file, request, path);
}
return ResData.success(url);
}
@GetMapping("/download")
public void download(@RequestParam String name, @RequestParam int open, HttpServletResponse response) throws ServerException {
if (local) {
FileUtils.downloadLocalFile(name, open, response, path);
}
}
@PostMapping("/delete")
public ResData<String> delete(@RequestParam String url) throws ServerException {
FileUtils.deleteFile(url);
return ResData.success();
}
@PostMapping("/wangeditorImage")
public WangEditorImage wangeditorImage(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws ServerException {
String url = "";
if (local) {
url = FileUtils.uploadFileToLocal(file, request, path);
}
String name = url.substring(url.lastIndexOf("/"));
Map<String, Object> data = new HashMap<>();
data.put("url", url);
data.put("alt", name);
data.put("href", url);
return new WangEditorImage(0, ResEnum.SUCCESS.getMsg(), data);
}
@PostMapping("/wangeditorVideo")
public WangEditorVideo wangeditorVideo(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws ServerException {
String url = null;
if (local) {
url = FileUtils.uploadFileToLocal(file, request, path);
}
Map<String, Object> data = new HashMap<>();
data.put("url", url);
data.put("poster", "");
return new WangEditorVideo(0, ResEnum.SUCCESS.getMsg(), data);
}
}
FileUtils
package com.question.utils.upload;
import com.question.common.exception.ServerException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
@Component
public class FileUtils {
static final String BASE_PATH = System.getProperty("user.dir") + "/src/main/resources/static/upload/";
public static String uploadFileToLocal(MultipartFile multipartFile, HttpServletRequest request, String path) throws ServerException {
String originalFilename = multipartFile.getOriginalFilename();
String fileExtension = "";
if (originalFilename.lastIndexOf(".") != -1) {
fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
}
String newFilename = originalFilename;
File file =new File(path, newFilename);
if (path != null && !path.isEmpty() ) {
if( file.exists()){
newFilename= System.currentTimeMillis() + fileExtension;
file = new File(path, newFilename);
}else {
file = new File(path, originalFilename);
}
} else {
if( file.exists()){
newFilename= System.currentTimeMillis() + fileExtension;
file = new File(BASE_PATH, newFilename);
}else {
file = new File(BASE_PATH, originalFilename);
}
}
if (file.exists()) {
throw new ServerException("文件已存在");
}
File directory = file.getParentFile();
if (directory != null && !directory.exists()) {
directory.mkdirs();
}
try (InputStream fis = multipartFile.getInputStream();
FileOutputStream fos = new FileOutputStream(file)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
String contextPath = request.getContextPath();
String scheme = request.getScheme();
String serverName = request.getServerName();
int serverPort = request.getServerPort();
String portSuffix = (serverPort == 80 || serverPort == 443) ? "" : ":" + serverPort;
String basePath = scheme + "://" + serverName + portSuffix + contextPath + "/"+ "system" + "/" + "file" + "/" + "download";
return basePath + "?name=" + newFilename + "&open=1";
} catch (IOException e) {
throw new ServerException("上传失败");
}
}
public static void downloadLocalFile(@RequestParam String name,
int open,
HttpServletResponse response, String path) throws ServerException {
if (name.contains("..")) {
throw new ServerException("不合法的文件名");
}
String openStyle = open == 1 ? "inline" : "attachment";
File file = null;
if (path != null && !path.isEmpty()) {
file = new File(path, name);
} else {
file = new File(BASE_PATH, name);
}
if (!file.exists()) {
throw new ServerException("文件未找到");
}
try (InputStream inputStream = new FileInputStream(file);
OutputStream outputStream = response.getOutputStream()) {
response.setHeader("Content-Disposition", openStyle + ";filename=" + name);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
} catch (FileNotFoundException e) {
throw new ServerException("文件未找到");
} catch (IOException e) {
throw new ServerException("下载失败");
}
}
public static void deleteFile(String url) {
try {
String[] split = url.split("name=");
File file = new File(BASE_PATH + split[1]);
if (file.exists()) {
file.delete();
}
} catch (Exception e) {
throw new ServerException("删除失败");
}
}
private static boolean isImageExtension(String extension) {
return ".jpg".equalsIgnoreCase(extension) ||
".jpeg".equalsIgnoreCase(extension) ||
".png".equalsIgnoreCase(extension) ||
".gif".equalsIgnoreCase(extension) ||
".bmp".equalsIgnoreCase(extension);
}
private static boolean isVideoExtension(String extension) {
return ".mp4".equalsIgnoreCase(extension) ||
".avi".equalsIgnoreCase(extension) ||
".mov".equalsIgnoreCase(extension) ||
".wmv".equalsIgnoreCase(extension) ||
".mkv".equalsIgnoreCase(extension);
}
public static String uploadChunkFileToLocal(MultipartFile file, String fileName, int chunk, int chunks, String path, HttpServletRequest request) {
try {
String uploadDir;
if (path != null && !path.isEmpty()) {
uploadDir = path;
} else {
uploadDir = BASE_PATH;
}
String chunkFileName = uploadDir + fileName + "_" + chunk + ".part";
File chunkFile = new File(chunkFileName);
if (!chunkFile.exists()) {
chunkFile.createNewFile();
try (FileOutputStream fos = new FileOutputStream(chunkFile);
InputStream fis = file.getInputStream()) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
throw new ServerException("上传失败");
}
}
return null;
} catch (IOException e) {
throw new ServerException("上传失败");
}
}
public static String mergeChunks(String fileName, String path, HttpServletRequest request) {
try {
String extension = fileName.substring(fileName.lastIndexOf("."));
String newFileName = System.currentTimeMillis() + extension;
String uploadDir;
if (path != null && !path.isEmpty()) {
uploadDir = path;
} else {
uploadDir = BASE_PATH;
}
File mergeFile = new File(uploadDir, newFileName);
if (!mergeFile.exists()) {
mergeFile.createNewFile();
}
String[] chunkNames = new File(uploadDir).list((dir, name) -> name.startsWith(fileName) && name.endsWith(".part"));
if (chunkNames == null || chunkNames.length == 0) {
return null;
}
try (FileOutputStream fos = new FileOutputStream(mergeFile, true)) {
for (String chunkName : chunkNames) {
File chunkFile = new File(uploadDir + chunkName);
try (FileInputStream fis = new FileInputStream(chunkFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
}
chunkFile.delete();
}
}
String contextPath = request.getContextPath();
String scheme = request.getScheme();
String serverName = request.getServerName();
int serverPort = request.getServerPort();
String portSuffix = (serverPort == 80 || serverPort == 443) ? "" : ":" + serverPort;
String basePath = scheme + "://" + serverName + portSuffix + contextPath +"/" + "system" + "/" + "file" + "/" + "download";
return basePath + "?name=" + newFileName + "&open=1";
} catch (Exception e) {
throw new ServerException("合并失败");
}
}
}