【SpringBoot】文件上傳(基礎上傳、上傳文件限制、上傳多個文件)

文件上傳

文件上傳是Web開發非常重要的操作

結合SpringBoot實現文件上傳操作

1、基礎上傳

SpringBoot採用FileUpload組件實現上傳處理,在控制器中可以使用MultipartFile類進行接收。

FileUpload上傳 MultipartFile接收

1、建立上傳控制器UploadController,利用MultipartFile將上傳文件保存在本地磁盤。

一個上傳文件的接口,訪問接口選擇把要上傳的文件利用MultipartFile上傳保存在本地磁盤中。

@Controller
public class UploadController {
	//訪問http://localhost//upload_pre 顯示upload.html頁面
    @GetMapping("/upload_pre")
    public String uploadPre() { // 通過model可以實現內容的傳遞
        return "upload";
    }

    //upload
    @PostMapping("/upload")
    @ResponseBody
    public Object upload(String name, MultipartFile photo) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        if (photo != null) {    // 現在有文件上傳
        	//姓名
            map.put("name-param", name);
            //文件名
            map.put("photo-name", photo.getName());
            //文件類型 content-type: "image/png",
            map.put("content-type", photo.getContentType());
            //文件大小
            map.put("photo-size", photo.getSize());
            //eg: UUID + . + png
            String fileName = UUID.randomUUID() + "."
                    + photo.getContentType().substring(
                    photo.getContentType().lastIndexOf("/") + 1);    // 創建文件名稱
			//文件路徑  位置 + 文件名
			String filePath = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                    .getRequest().getServletContext().getRealPath("/") + fileName;
            //文件路徑
			map.put("photo-path", filePath);
            File saveFile = new File(filePath);
            photo.transferTo(saveFile);        // 文件保存
            return map;
        } else {
            return "nothing";
        }
    }
}


2、建立src/main/view/templates/upload.html頁面

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<title>文件上傳</title>
	<script type="text/javascript" th:src="@{/js/main.js}"></script> 
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>
	<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
		姓名:<input type="text" name="name"/><br/>
		照片:<input type="file" name="photo"/><br/>
		<input type="submit" value="上傳"/>
	</form>
</body>
</html>

執行

upload.html頁面表單填入姓名和選擇圖片點擊上傳向upload接口傳遞了姓名(文本)和圖片(二進制數據)兩個數據信息。控制器接收到此請求信息後,返回JSON格式信息

{
photo-size: 23902,
content-type: "image/png",
photo-path: "C:\Windows\Temp\tomcat-docbase.6786357466203986968.80\2a220798-ecbe-4fae-a1c9-485d75d7dfe1.png",
photo-name: "photo",
name-param: "liuawen"
}

2、上傳文件限制

在實際項目開發中,需要對用戶上傳文件的大小進行限制,這樣纔可以保證服務器的資源不被浪費。 配置yml實現上傳限制

1、修改application.yml配置文件,增加上傳限制。

application.yml

spring:
  http:
    multipart:
      enabled: true           # 啓用http上傳
      max-file-size: 10MB     # 設置支持的單個上傳文件的大小限制
      max-request-size: 20MB  # 設置最大的請求的文件大小,設置總體大小請求
      file-size-threshold: 512KB   # 當上傳文件達到指定配置量的時候會將文件內容寫入磁盤
      location: /             # 設置上傳的臨時目錄

2、對於上傳限制,也可以利用Bean實現同樣的效果。·

cn.liuawen.config UploadConfig.java

@Configuration
public class UploadConfig {
	@Bean
	public MultipartConfigElement getMultipartConfig() {
		MultipartConfigFactory config = new MultipartConfigFactory() ;
		config.setMaxFileSize("100KB"); 			// 設置上傳文件的單個大小限制
		config.setMaxRequestSize("20MB"); 		// 設置總的上傳的大小限制
		config.setLocation("/"); 				// 設置臨時保存目錄
		return config.createMultipartConfig() ;	// 創建一個上傳配置
	}
}

設置上傳文件的單個大小限制

爲了測試我把上傳文件的單個大小限制設置小了點 看測試是否有異常

上傳了個195KB的

http://localhost/upload

上傳出錯後頁面執行的效果

錯誤路徑:http://localhost/upload

錯誤信息:Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field photo exceeds its maximum permitted size of 102400 bytes.

錯誤 圖片太大了,用戶上傳的內容超過了配置的限制,全局異常處理 。

3、上傳多個文件

如果要進行多個文件的上傳,需要通過MultipartHttpServletRequest進行文件接收。

1、修改upload.html頁面,定義多個文件上傳控件。

upload.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<title>SpringBoot多文件上傳</title>
	<script type="text/javascript" th:src="@{/js/main.js}"></script> 
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>

	<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
		姓名:<input type="text" name="name"/><br/>
<!--		選擇多個文件上傳  這裏是一個個的呀-->
		照片1:<input type="file" name="photo"/><br/>
		照片2:<input type="file" name="photo"/><br/>
		照片3:<input type="file" name="photo"/><br/>
		<input type="submit" value="上傳"/>
	</form>
</body>
</html>

2、修改UploadController控制器,實現多個文件上傳。

@Controller
public class UploadController {
	@GetMapping("/upload_pre")
	public String uploadPre() { // 通過model可以實現內容的傳遞
		return "upload";
	}
	@PostMapping("/upload")
	@ResponseBody
	public Object upload(String name, HttpServletRequest request) {  
		List<String> result = new ArrayList<String>() ;
		//多個文件上傳  就只是簡單的多文件上傳保存在本地的磁盤
		if (request instanceof MultipartHttpServletRequest) {
			MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest) request;
			//<input type="file" name="photo"/>
			List<MultipartFile> files = mrequest.getFiles("photo");
			Iterator<MultipartFile> iter = files.iterator();
			while (iter.hasNext()) {
				MultipartFile photo = iter.next() ;		// 取出每一個上傳文件
				try {
					result.add(this.saveFile(photo)) ;		// 保存上傳信息
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return result ; 
	}
	/**
	 * 文件保存處理
	 * @param file 上傳文件
	 * @return 文件保存路徑 
	 * @throws Exception 上傳異常
	 */
	public String saveFile(MultipartFile file) throws Exception {
		String path = "nothing" ;
		if (file != null) {					// 有文件上傳
			if (file.getSize() > 0) {
				String fileName = UUID.randomUUID() + "."
						+ file.getContentType().substring(
								file.getContentType().lastIndexOf("/") + 1);	// 創建文件名稱
				path = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
						.getRequest().getServletContext().getRealPath("/") + fileName;
				File saveFile = new File(path) ;
				file.transferTo(saveFile);		// 文件保存
			}
		} 
		return path ;
	}
}


3、測試

http://localhost/upload_pre

在這裏插入圖片描述
http://localhost/upload

[
"C:\Windows\Temp\tomcat-docbase.1489099008397591870.80\c97e9432-4716-4ef8-93d0-d18f3b4ab74d.png",
"C:\Windows\Temp\tomcat-docbase.1489099008397591870.80\09bab86d-44bd-426e-8d5c-9d7c17929ae7.png",
"C:\Windows\Temp\tomcat-docbase.1489099008397591870.80\5d30e2de-f83a-4113-8c96-69b3e92de086.png"
]

在這裏插入圖片描述

爲了方便文件上傳,就簡單在控制器類中定義了一個saveFile()方法,以進行文件的保存,同時利用此方法返回了上傳文件的保存路徑。

這裏的保存上傳圖片都是保存到本地磁盤的,
假的上傳😂
實際開發不是這樣的,在當今的項目開發中,最流行的設計理念是高可用、高併發、分佈式設計,所以在實際項目中需要搭建專門的圖片服務器進行上傳資源的保存。

圖片服務器集羣

4、參考資料

簡單記錄

1、名師講壇:Java微服務架構實戰(SpringBoot+SpringCloud+Docker+RabbitMQ)- 李興華

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章