Spring Framework 6 教學 (十二) MVC 檔案上傳

  • Post category:Spring 6 / MVC

Spring Framework 6 MVC 檔案上傳的機制,需要啟用 StandardServletMultipartResolver ,並且在 web.xml 中,設定 <multipart-config> 相關設定。

Spring Framework 6 MVC 檔案上傳的表單

建立uploadMultiple.jsp

在 Html 頁面上,由表單進行上傳。

表單須設定為 post ,且為 enctype=”multipart/form-data” ,如下:

<form method="POST" action="uploadFile1" enctype="multipart/form-data">
		File1 to upload: <input type="file" name="document"><br /> 
		Name1: <input type="text" name="name"><br /> <br /> 
		<input type="submit" value="Upload"> Press here to upload the file!
	</form>

建立第二個 jsp 單純顯示上傳後的訊息。fileok.jsp

Spring Framework 6 MVC 檔案上傳設定 web.xml

在設定 DispatcherServlet 的標籤中,要增加 <multipart-config> ,如下:

 <servlet-name>dispatcher</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <multipart-config>
      <location>/var/tmp</location>
      <max-file-size>104857600</max-file-size>
      <max-request-size>104857600</max-request-size>
      <file-size-threshold>0</file-size-threshold>
    </multipart-config>
 </servlet>
  • fileSizeThreshold:我們可以指定檔案將寫入磁碟的大小閾值。大小值以位元組為單位,因此 1024*1024*10 為 10 MB。
  • location:預設儲存檔案的目錄,預設值為「」。
  • maxFileSize:允許上傳檔案的最大大小,其值以位元組為單位。預設值為-1L,表示無限制。
  • maxRequestSize:多部分/表單資料請求允許的最大大小。預設值為-1L,表示無限制。

Spring Framework 6 MVC 檔案上傳的 Controller

Java 程式,接收檔案會使用 @RequestPart ,接收一般的參數仍用 @RequestParam

利用 java.io.path 的物件,進行檔案的存檔。

如下:

package com.tcg.action;

import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class FileUploadAction {

	@PostMapping("uploadFile1")
	public String fileForm(@RequestParam String name, @RequestPart MultipartFile document) {
		System.out.println("fileForm...");
		
		store(document);
		return "fileok";
	}
	
	
	public void store(MultipartFile file) {
		try {
			if (file.isEmpty()) {
				throw new Exception("Failed to store empty file.");
			}
			String rootPath = System.getProperty("catalina.home");
			Path rootLocation = Paths.get(rootPath );
			Path destinationFile = rootLocation.resolve(
					Paths.get(file.getOriginalFilename()))
					.normalize().toAbsolutePath();
			System.out.println("rootLocation:"+rootLocation);
			System.out.println("destinationFile:"+destinationFile);
			if (!destinationFile.getParent().equals(rootLocation.toAbsolutePath())) {
				// This is a security check
				throw new Exception(
						"Cannot store file outside current directory.");
			}
			try (InputStream inputStream = file.getInputStream()) {
				Files.copy(inputStream, destinationFile,
					StandardCopyOption.REPLACE_EXISTING);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Spring Framework 6 MVC 檔案上傳在 eclipse 的 Tomcat 測試

若發生

The temporary upload location [C:\wk3.metadata.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\SpringMVC\var\tmp] is not valid

則需要在 Tomcat 的 server.xml 找到專案並設定屬性

createUploadTargets=”true”

這個屬性是讓 Tomcat 應嘗試為 Servlet 的 MultipartConfig 中指定的暫時上傳位置建立位置(如果位置尚不存在),請設為 true。如果未指定,則會使用預設值 false

檔案可以上傳成功