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” ,如下:

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

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

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

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

 &lt;servlet-name>dispatcher&lt;/servlet-name>
 &lt;servlet-class>org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class>
 &lt;multipart-config>
      &lt;location>/var/tmp&lt;/location>
      &lt;max-file-size>104857600&lt;/max-file-size>
      &lt;max-request-size>104857600&lt;/max-request-size>
      &lt;file-size-threshold>0&lt;/file-size-threshold>
    &lt;/multipart-config>
 &lt;/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

檔案可以上傳成功