說明:通常項目中,如果圖片比較多的話,都會把圖片放在專門的服務器上,而不會直接把圖片放在業務代碼所在的服務器上。下面的例子只是為了學習基本流程,所以放在了本地。
1、單張圖片上傳
1.1、前端用表單提交
前端代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" action="/uploads" enctype="multipart/form-data">
<input type="file" name="files" multiple>
<input type="submit" value="上傳">
</form>
</body>
</html>
后端代碼;
SimpleDateFormat formatter = new SimpleDateFormat("/yyyy/MM/dd/"); @RequestMapping("/upload") public String fileUpload(MultipartFile file, HttpServletRequest request){ String time = formatter.format(new Date()); //圖片上傳服務器后所在的文件夾 String realPath = request.getServletContext().getRealPath("/img") + time; File folder = new File(realPath); if(!folder.exists()) folder.mkdirs(); //通常需要修改圖片的名字(防止重復) String oldName = file.getOriginalFilename(); String newName = UUID.randomUUID() + oldName.substring(oldName.lastIndexOf(".")); try { //將文件放到目標文件夾 file.transferTo(new File(folder, newName)); //通常還需要返回圖片的URL,為了通用性,需要動態獲取協議,不要固定寫死 String returnUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/img" + time + newName; return returnUrl; } catch (IOException e) { e.printStackTrace(); } return null; }
1.2、前端用ajax提交
前端代碼與上面的略有不同,后台代碼是一樣的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="file" id="file"> <input type="submit" value="上傳" onclick="uploadFile()"> <h1 id="result"></h1> </body> <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"> </script> <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> </html>
2、多個圖片上傳
前端代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post" action="/uploads" enctype="multipart/form-data"> <input type="file" name="files" multiple> <input type="submit" value="上傳"> </form> </body> </html>
后台代碼:
@RequestMapping("/uploads")
public String fileUploads(MultipartFile[]files, HttpServletRequest request){
String time = formatter.format(new Date());
//圖片上傳服務器后所在的文件夾
String realPath = request.getServletContext().getRealPath("/img") + time;
File folder = new File(realPath);
if(!folder.exists())
folder.mkdirs();
for (MultipartFile file : files) {
//通常需要修改圖片的名字(防止重復)
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID() + oldName.substring(oldName.lastIndexOf("."));
try {
//將文件放到目標文件夾
file.transferTo(new File(folder, newName));
//通常還需要返回圖片的URL,為了通用性,需要動態獲取協議,不要固定寫死
String returnUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/img" + time + newName;
System.out.println(returnUrl);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
3、問題記錄
在后台代碼中,有一行需要注意下:
String realPath = request.getServletContext().getRealPath("/img") + time;
需要理解一下realPath究竟指的是什么。剛開始測試的時候,圖片上傳成功后,后台idea里找不到對應的圖片,然后根據它返回的realPath,在C盤用戶目錄下的某個文件夾里找到了該圖片(user/AppData/....)。
參考博客: https://www.cnblogs.com/netcorner/p/12001668.html
shift+shift 全局搜索 getCommonDocumentRoot這個方法,點進去,有個靜態數組:COMMON_DOC_ROOTS
private static final String[] COMMON_DOC_ROOTS = new String[]{"src/main/webapp", "public", "static"};
發現默認是指webapp下,或者根目錄下的public、static文件夾(與src並列)。然而這些目錄都沒有,所以Spring定向到了工程目錄以外的一個位置。
於是我在根目錄下新建一個static文件夾,再次上傳,果然有效了。

