一、前期配置
同樣不需要額外配置添加一個 web 功能模塊即可
二、單文件上傳
上傳頁面 index.html
位置放在了 static 目錄下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--enctype:encodetype編碼類型-->
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="提交">
</form>
</body>
</html>
知識點:enctype="multipart/form-data"
enctype 意思是encodetype就是編碼類型
multipart/form-data
是指表單數據有多部分構成,既有文本數據,又有文件等二進制數據的意思。
需要注意的是:默認情況下,enctype的值是application/x-www-form-urlencoded
,不能用於文件上傳,只有使用了multipart/form-data,才能完整的傳遞文件數據
FileUploadController:
@RestController
public class FileUploadController {
private static final Logger log = LoggerFactory.getLogger(FileUploadController.class);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//MultipartFile 這個類一般是用來接受前臺傳過來的文件
@PostMapping("/upload")
public Map<String, String> upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
//日誌打印文件信息
log.info("[文件類型] - [{}]", file.getContentType());
log.info("[文件名稱] - [{}]", file.getOriginalFilename());
log.info("[文件大小] - [{}]", file.getSize());
//設置存儲位置
String format = sdf.format(new Date());
String path = "D:\\flv\\" + format;
System.out.println(path);
File folder = new File(path);
if (!folder.exists()) {
folder.mkdirs();
}
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
//將文件寫入到指定的目錄中
file.transferTo(new File(folder, newName));
System.out.println("getScheme:" + request.getScheme());
System.out.println("getServerName:" + request.getServerName());
System.out.println("getServerPort" + request.getServerPort());
//頁面回顯數據
Map<String, String> result = new HashMap<>(16);
result.put("contentType", file.getContentType());
result.put("fileName", file.getOriginalFilename());
result.put("fileSize", file.getSize() + "");
return result;
}
}
知識點:HashMap(int initialCapacity)
hashMap源碼中initialCapacity的初始值爲16,負載因子爲0.75;
所以一個hashMap中默認存儲長度爲16 * 0.75 = 12,也就是如果hashMap.put的鍵值對數量小於12的時候,hashMap位置夠用;但是當添加的鍵值對數超過12後,hashMap需要擴容,一倍,也就是長度從12擴容到24;
例如鍵值對一共13個,這樣剩餘11個位置性能都浪費了,那麼如果已知需要添加的鍵值對數量,就可以通過設置initialMap的值,來避免hashMap擴容,減少性能消耗。
eg:我們需要往hashMap中添加6個鍵值對,6 / 0.75 = 8;那就可以把initialCapacity設置爲9比較合適,節省性能。
三、多文件上傳
index.html
<form action="/uploads" method="post" enctype="multipart/form-data">
<input type="file" name="files" multiple>
<input type="submit" value="提交">
</form>
FileUploadController:
@PostMapping("/uploads")
public String uploads(@RequestParam("files") MultipartFile[] files, HttpServletRequest request) throws IOException {
//設置存儲位置
String format = sdf.format(new Date());
String path = "D:\\flv\\" + format;
System.out.println(path);
File folder = new File(path);
if (!folder.exists()) {
folder.mkdirs();
}
for (MultipartFile file : files) {
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
//將文件寫入到指定的目錄中
file.transferTo(new File(folder, newName));
String filePath = path + "\\" + newName;
System.out.println(filePath);
}
return "success";
}
四、Ajax 實現文件上傳
主要是請求你頁面的改變,對於
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery3.3.1.js"></script>
</head>
<body>
<div id="result"></div>
<input type="file" id="file">
<input type="button" value="上傳" onclick="uploadFile()">
<script>
function uploadFile() {
var file = $("#file")[0].files[0];
var formData = new FormData();
formData.append("file", file);
$.ajax({
type:'post',
url:'/upload',
processData:false,
contentType:false,
data:formData,
success:function (msg) {
$("#result").html(msg);
}
})
}
</script>
</body>
</html>
知識點:Ajax 屬性
processData:處理數據
默認情況下,processData 的值是 true,其代表以對象的形式上傳的數據都會被轉換爲字符串的形式上傳。而當上傳文件的時候,則不需要把其轉換爲字符串,因此要改成false
contentType:發送數據的格式
和 contentType 有個類似的屬性是 dataType , 代表的是期望從後端收到的數據的格式,一般會有 json 、text……等而 contentType 則是與 dataType 相對應的,其代表的是前端發送數據的格式,默認值:application/x-www-form-urlencoded
,代表的是 ajax 的 data 是以字符串的形式 如 id=2019&password=123456 使用這種傳數據的格式,無法傳輸複雜的數據,比如多維數組、文件等
url:請求路徑
data:請求參數
callback:回調函數
type:響應結果的類型
有時候要注意,自己所傳輸的數據格式和ajax的contentType格式是否一致,如果不一致就要想辦法對數據進行轉換
把contentType 改成 false 就會改掉之前默認的數據格式,在上傳文件時就不會報錯了。
五、屬性配置
默認情況下 Spring Boot 無需做任何配置也能實現文件上傳的功能,但有可能因默認配置不符而導致文件上傳失敗問題,
所以也可以按照對應的情況在 application.properties
中設置對應的屬性;
# 上傳文件的臨時目錄 (一般情況下不用特意修改)
spring.servlet.multipart.location=
# 上傳文件最大爲 1M (默認值 1M 根據自身業務自行控制即可)
spring.servlet.multipart.max-file-size=1048576
# 判斷是否要延遲解析文件(相當於懶加載,一般情況下不用特意修改)
spring.servlet.multipart.resolve-lazily=false
# 禁用 thymeleaf 緩存
spring.thymeleaf.cache=false
# 是否支持批量上傳 (默認值 true)
spring.servlet.multipart.enabled=true
# 上傳請求最大爲 10M(默認值10M 根據自身業務自行控制即可)
spring.servlet.multipart.max-request-size=10485760
# 文件大小閾值,當大於這個閾值時將寫入到磁盤,否則存在內存中,(默認值0 一般情況下不用特意修改)
spring.servlet.multipart.file-size-threshold=0