【SpringMVC】SpringMVC 實現檔案上傳
阿新 • • 發佈:2020-12-24
SpringMVC 實現檔案上傳
檔案上傳回顧
實現步驟:
- 客戶端:
- 傳送 post 請求,告訴伺服器要上傳什麼檔案
- 伺服器:
- 要有一個
form
標籤,method=post
請求,form 標籤的 encType 屬性值必須為multipart/form-data
值 - 在
form
標籤中使用input type=file
新增上傳的檔案接收並處理上傳的檔案
- 要有一個
檔案上傳時 HTTP 協議說明:
Content-type
表示提交的資料型別multipart/form-data
表示提交的資料,以多段(每一個表單項代表一個數據段)的形式進行拼接,然後以二進位制流的形式傳送給伺服器boundary
表示每段資料的分隔符,它的值是有瀏覽器隨機生成的,它是每段資料的分割符
實現上傳下載功能常用兩個包:
commons-fileupload-1.3.1.jar
commons-io-2.4.jar
FileUploadController.java
@Controller @RequestMapping("/file") public class FileUploadController { /** * 檔案上傳回顧 * @return */ @RequestMapping(path = {"/upload1"}) public String upload1(HttpServletRequest request) throws Exception { System.out.println("called upload1..."); String path = request.getSession().getServletContext().getRealPath("/uploads"); // 獲取到要上傳的檔案目錄 System.out.println(path); File file = new File(path); if (!file.exists()) { file.mkdirs(); } DiskFileItemFactory factory = new DiskFileItemFactory(); // 建立磁碟檔案項工廠 ServletFileUpload fileUpload = new ServletFileUpload(factory); List<FileItem> fileItems = fileUpload.parseRequest(request); // 解析request物件 for (FileItem fileItem : fileItems) { if (fileItem.isFormField()) { // 判斷檔案項是普通欄位,還是上傳的檔案 System.out.println(fileItem.getName()); } else { String itemName = fileItem.getName(); // 獲取到上傳檔案的名稱 itemName = UUID.randomUUID().toString() + "-" + itemName; // 把檔名唯一化 fileItem.write(new File(file, itemName)); // 上傳檔案 fileItem.delete(); } } return "success"; } }
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>檔案上傳</title> </head> <body> <h3>檔案上傳回顧</h3> <form action="file/upload1" method="post" enctype="multipart/form-data"> 名稱:<input type="text" name="picName"/><br/> 圖片:<input type="file" name="picFile"/><br> <input type="submit" value="上傳檔案"/> </form> </body> </html>
SpringMVC 傳統方式的檔案上傳
傳統方式的檔案上傳,指的是我們上傳的檔案和訪問的應用存在於同一臺伺服器上。並且上傳完成之後,瀏覽器可能跳轉。
SpringMVC 框架提供了 MultipartFile 物件,該物件表示上傳的檔案,要求變數名稱必須和表單 file 標籤的 name 屬性名稱相同。並且需要配置檔案解析器物件。
<!-- 配置 檔案解析器,要求 id 名稱必須是 multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
FileUploadController.java
@Controller
@RequestMapping("/file")
public class FileUploadController {
/**
* SpringMVC 傳統方式的檔案上傳
* @return
*/
@RequestMapping(path = {"/upload2"})
public String upload2(HttpServletRequest request, String picName, MultipartFile picFile) throws Exception {
System.out.println("called upload2...");
String path = request.getSession().getServletContext().getRealPath("/uploads"); // 獲取到要上傳的檔案目錄
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
String fileName = picName + "-" + picFile.getOriginalFilename();
fileName = UUID.randomUUID().toString() + "-" + fileName;
picFile.transferTo(new File(file, fileName)); // 上傳檔案
return "success";
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>檔案上傳</title>
</head>
<body>
<h3>SpringMVC 傳統方式檔案上傳</h3>
<form action="file/upload2" method="post" enctype="multipart/form-data">
名稱:<input type="text" name="picName"/><br/>
圖片:<input type="file" name="picFile"/><br>
<input type="submit" value="上傳檔案"/>
</form>
<br>
</body>
</html>
SpringMVC 跨伺服器方式的檔案上傳
在實際開發中,可能會有很多處理不同功能的伺服器。例如:
- 應用伺服器:負責部署應用
- 資料庫伺服器:執行資料庫
- 快取和訊息伺服器:負責處理大併發訪問的快取和訊息
- 檔案伺服器:負責儲存使用者上傳檔案的伺服器
分伺服器處理的目的是讓伺服器各司其職,從而提高專案的執行效率。
準備兩個 Tomcat 伺服器,注意 HTTP Port 和 JMX Port 不能相同。
一個用作檔案伺服器,並建立一個用於存放檔案的 web 工程。檔案伺服器原始碼,並修改檔案伺服器的 web.xml 配置,使其可以支援寫入操作,搜尋 DefaultServlet,新增以下程式碼:
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
另一個 Tomcat 伺服器,編寫以下程式碼
FileUploadController.java
@Controller
@RequestMapping("/file")
public class FileUploadController {
/**
* SpringMVC 跨伺服器方式的檔案上傳
* @return
*/
@RequestMapping(path = {"/upload3"})
public String upload3( String picName, MultipartFile picFile) throws Exception {
System.out.println("called upload3...");
String path = "http://localhost:9090/file-server/uploads/"; // 定義上傳檔案伺服器路徑
String fileName = picName + "-" + picFile.getOriginalFilename();
fileName = UUID.randomUUID().toString() + "-" + fileName;
// 1. 建立客戶端物件
Client client = Client.create();
// 2. 和檔案伺服器進行連線
WebResource resource = client.resource(path + fileName);
// 3. 上傳檔案,跨伺服器的
resource.put(picFile.getBytes());
return "success";
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>檔案上傳</title>
</head>
<body>
<h3>SpringMVC 跨伺服器方式檔案上傳</h3>
<form action="file/upload3" method="post" enctype="multipart/form-data">
名稱:<input type="text" name="picName"/><br/>
圖片:<input type="file" name="picFile"/><br>
<input type="submit" value="上傳檔案"/>
</form>
</body>
</html>