上代码:
请求方式:Content-Type multipart/form-data;
单文件上传
控制层
@PostMapping("/uploadFile")
public ResponseData<String> uploadFile(@RequestParam("file") MultipartFile file,HttpServletRequest request) throws IOException {
return fileService.uploadFile(file,request);
}
实现层
@Override
public ResponseData<String> uploadFile(MultipartFile file, HttpServletRequest request) throws IOException {
String oldFileName = file.getOriginalFilename();
String exname = null;
if (oldFileName != null) {
exname = oldFileName.substring(oldFileName.lastIndexOf("."));
String newFileName = IdUtil.createId() + exname;
String path = upload + "/" + newFileName;
File fileUploadPath = new File(path);
if (!fileUploadPath.exists()) {
fileUploadPath.createNewFile();
}
try {
file.transferTo(fileUploadPath);
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/file/showFile?name=" + newFileName;
return ResponseData.success("上传成功", basePath);
} catch (IOException e) {
e.printStackTrace();
}
}
return ResponseData.failure("上传失败");
}
多文件上传
控制层
@PostMapping("/uploadAnyFile")
public ResponseData<List<String>> uploadAnyFile(HttpServletRequest request) throws IOException, ServletException {
return fileService.uploadAnyFile(request);
}
实现层
@Override
public ResponseData<List<String>> uploadAnyFile(HttpServletRequest request) throws IOException, ServletException {
Collection<Part> parts = request.getParts();
List<String> list = new ArrayList<>();
parts.forEach(part -> {
String fileName = part.getSubmittedFileName();
String exname = fileName.substring(fileName.lastIndexOf("."));
InputStream inputStream = null;
OutputStream outputStream = null;
try {
String name = IdUtil.createId() + exname;
inputStream = part.getInputStream();
File file = new File(upload + "/" + name);
if (!file.exists()) {
file.createNewFile();
}
outputStream = new FileOutputStream(file);
int i = FileCopyUtils.copy(inputStream, outputStream);
long size = part.getSize();
if (i == size) {
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/file/showFile?name=" + name;
list.add(basePath);
} else {
file.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
});
if (parts.size() == list.size()) {
return ResponseData.success("文件上传成功", list);
}
return ResponseData.failure("文件上传失败");
}
文件预览
控制层
@GetMapping("/showFile")
public void showFile(HttpServletRequest request, HttpServletResponse response) {
fileService.showFile(request,response);
}
实现层
@Override
public void showFile(HttpServletRequest request, HttpServletResponse response) {
String name = request.getParameter("name");
String path = upload + "/" + name;
try (FileImageInputStream input = new FileImageInputStream(new File(path));
OutputStream out = response.getOutputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream()) {
byte[] buf = new byte[1024];
int len = -1;
while ((len = input.read(buf)) != -1) {
output.write(buf, 0, len);
}
byte[] data = output.toByteArray();
out.write(data);
out.flush();
} catch (IOException ex) {
ex.printStackTrace();
log.error("文件预览发生异常:{}", ex.getMessage());
}
}
大文件分片,断点续传
Hmlt
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div>
<input type="file" id="pick" value="选择文件"/>
<input type="submit" id="submit" value="上传文件"/>
div>
<script th:src="@{/js/jquery.min.js}">script>
<script>
$(function () {
let file;
let elementById = window.document.getElementById("pick");
elementById.addEventListener('change', function () {
file = elementById.files[0]
})
let submit = window.document.getElementById("submit");
submit.addEventListener('click', function () {
let maxSize = 2 * 1024 * 1024;
let index = 0;
let size = file.size;
let ceil = Math.ceil(size / maxSize);
let exname = file.name.substr(file.name.lastIndexOf("."))
let chunks = [];
if (ceil > 50) {
ceil = 50
maxSize = size / ceil;
}
while (index < ceil) {
chunks.push({
file: file.slice(index * maxSize, (index + 1) * maxSize),
filename: "chunk_" + index + exname,
chunk: index
})
index++;
}
var i = 1;
chunks.forEach(f => {
let formdata = new FormData();
formdata.append("file", f.file);
formdata.append("filename", f.filename)
$.ajax({
url: "/file/uploadBigFile",
headers: {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlkIjpudWxsLCJleHAiOjE2NTU4Nzc2NjMsImlhdCI6MTY1NTI3Mjg2MywidXNlcm5hbWUiOiJhZG1pbiJ9.qI7tGsvZ4rVcZXni1X20-ouaZOr5veItZdTc63K6ZwI"
},
type: "post",
data: formdata,
contentType: false,
processData: false,
success: function (data) {
if (i === ceil) {
console.log("合并文件")
$.ajax({
url: "/file/mergeBigFile",
headers: {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlkIjpudWxsLCJleHAiOjE2NTU4Nzc2NjMsImlhdCI6MTY1NTI3Mjg2MywidXNlcm5hbWUiOiJhZG1pbiJ9.qI7tGsvZ4rVcZXni1X20-ouaZOr5veItZdTc63K6ZwI"
},
type: "get",
data: {
"chunks": ceil,
"exname": exname
},
success: function (data) {
console.log(data)
}
})
}
i++;
}
})
})
})
})
script>
body>
html>
控制层
@PostMapping("/uploadBigFile")
public ResponseData<String> uploadBigFile(@RequestParam("file") MultipartFile file,@RequestParam("filename") String filename) {
return fileService.uploadBigFile(file,filename);
}
@GetMapping("/mergeBigFile")
public ResponseData<String> mergeBigFile(@RequestParam("chunks")Integer chunks,String exname) {
return fileService.mergeBigFile(chunks,exname);
}
实现层
@Override
public ResponseData<String> uploadBigFile(MultipartFile file, String filename) {
try {
String path = upload + "/" + filename;
File fileUploadPath = new File(path);
if (!fileUploadPath.exists()) {
fileUploadPath.createNewFile();
file.transferTo(fileUploadPath);
}
return ResponseData.success("上传成功", "");
} catch (IOException e) {
e.printStackTrace();
}
return ResponseData.failure("上传文件失败");
}
@Override
public ResponseData<String> mergeBigFile(Integer chunks,String exname) {
RandomAccessFile raf = null;
try {
File file = new File(upload+"/"+IdUtil.createId()+exname);
if (!file.exists()) {
file.createNewFile();
}
raf = new RandomAccessFile(file, "rw");
for (int i = 0; i < chunks; i++) {
File file1 = new File(upload + "/chunk_" + i + exname);
RandomAccessFile reader = new RandomAccessFile(file1, "r");
byte[] b = new byte[1024];
int n = 0;
while ((n = reader.read(b)) != -1) {
raf.write(b, 0, n);
}
reader.close();
if (file1.exists()) {
file1.delete();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ResponseData.success("文件上传成功");
}
IdUtil
@Component
public class IdUtil {
private static Snowflake snowflake=null;
public static String createId () {
if(StrUtil.isBlankIfStr (snowflake)){
snowflake = cn.hutool.core.util.IdUtil.getSnowflake (1, 1);
}
return snowflake.nextId ()+"";
}
}