ssm/springboot架構實作多檔案上傳–MultipartFile類+multiple屬性+Ajax
首先搭建一個 SSM 或者 Spring Boot 項目,這裡簡單起見,項目就自行搭建了,直接用現成的一個 Spring Boot 項目來做這個功能實作。(
代碼可以直接用在兩種項目上
)
接下來開始功能實作:
1.首先建立一個 upload.ftl 檔案,
如果用的是JSP就建立 upload.jsp,其他模闆如thymeleaf、Freemarker、Velocity,就建相應的
,這裡我這個項目已經配置了用freemarker,是以就直接建立 ftl 檔案了。
增加一個 form 表單,form 表單裡面添加兩個控件,一個用來選擇要上傳的檔案,一個是用來送出表單的按鈕。
接下來,利用 ajax 來控制實作表單送出,這裡在
<head>
中引入 jQuery,友善開發
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
建立
<Script>
标簽編寫JavaScript ,為上面的按鈕綁定一個點選事件
寫到這裡,前端頁面就算寫好了,接下來寫後端代碼。建立一個 / 利用現有的 XxxxController.java 中建立兩個方法,一個跳轉到上傳頁面,一個實作上傳功能。如下:
跳轉頁面方法:
實作上傳功能方法:
到這裡,SSM / Spring Boot 架構的多檔案上傳功能就已經實作了。下面開始測試。啟動項目
浏覽器輸入:http://localhost:8081/cjcc,
這裡的 /cjcc 就是上面 controller 方法的 @GetMapping("/cjcc")
,并按 F12 打開開發人員工具–> newwork,友善測試。
點選選擇檔案按鈕,選擇需要上傳的檔案
上傳成功之後,檢視 Java 的控制台,看看設定輸出的内容
至此,多檔案已經成功上傳。
本次寫的多檔案上傳主要用到了:
1.MultipartFile 類
import org.springframework.web.multipart.MultipartFile;
MultipartFile 類是用來接收前台傳過來的檔案,常用的方法如下:
String getContentType() //擷取檔案MIME類型
InputStream getInputStream() //擷取檔案流
String getName() //擷取表單中檔案元件的名字
String getOriginalFilename() //擷取上傳檔案的原名
long getSize() //擷取檔案的位元組大小,機關byte,除以1024就是kb
boolean isEmpty() //是否為空
void transferTo(File dest) //儲存到一個目标檔案中。
2.multiple屬性(
HTML5 新屬性
)
multiple 屬性是一個布爾屬性。
multiple 屬性規定允許使用者輸入到 <input> 元素的多個參數值。
注意:multiple 屬性适用于以下 input 類型:email 和 file。
例如:
<!--上傳表單-start-->
<form enctype="multipart/form-data" id="form" method="post">
<!--構造一個input控件,類型為 file, HTML5中 multiple 屬性規定輸入字段可選擇多個值 -->
<input name="file" type="file" multiple>
<!--構造一個input控件,為控件綁定一個id=upload,類型為 button,名稱為:上傳-->
<input id="upload" type="button" value="上傳">
</form>
<!--上傳表單-end-->
3.jQuery的Ajax
AJAX = 異步 JavaScript 和 XML(Asynchronous JavaScript and XML)。
簡短地說,在不重載整個網頁的情況下,AJAX 通過背景加載資料,并在網頁上進行顯示。
GET 基本上用于從伺服器獲得(取回)資料。注釋:GET 方法可能傳回緩存資料。
POST 也可用于從伺服器擷取資料。不過,POST 方法不會緩存資料(請求頭中的Cache-Control: no-cache),并且常用于連同請求一起發送資料。
功能完整代碼:
HTML:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>ssm/springboot架構實作多檔案上傳</title>
<!--引入jQuery-->
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<h2>多檔案上傳</h2>
<!--上傳表單-start-->
<form enctype="multipart/form-data" id="form" method="post">
<!--構造一個input控件,類型為 file, HTML5中 multiple 屬性規定輸入字段可選擇多個值 -->
<input name="file" type="file" multiple>
<!--構造一個input控件,為控件綁定一個id=upload,類型為 button,名稱為:上傳-->
<input id="upload" type="button" value="上傳">
</form>
<!--上傳表單-end-->
</body>
<script>
/**
* 上傳按鈕的點選事件
*/
$("#upload").click(function () {
//因為new FormData(HtmlElement),需要的是HtmlElement類型,如果利用jQuery擷取,得到的是一個HtmlElement的集合,是以我們要取第一個值需要加下标$("#form")[0]
//JQuery 寫法 $("#form")[0] 等價于原生JavaScript的 document.getElementById("form");
//既然這裡已經導入了jQuery,那就用jQuery版本的寫法
var formData = new FormData($("#form")[0]);
//發送 ajax 請求
$.ajax("/uploadVideo2", {
method: "POST", //請求類型
data: formData, //請求資料
async: false, //不開啟異步,異步就是在執行到$.ajax({})的時候新開一個線程執行請求,主線程繼續往$.ajax({})函數下面執行,等到後端傳回請求結果之後再觸發success或者error函數
cache: false, //不使用緩存,GET請求需要可以加,這裡的POST請求本身就不會被緩存
contentType: false, //避免jQuery影響上面form表單設定的 enctype="multipart/form-data"類型,在F12中可以看到Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryW44OhJyyAytghmVT,"multipart/form-data"類型包含了boundary分界線作為多檔案之間區分的邊界
processData: false, //避免data資料轉化為字元串,在application/x-www-form-urlencoded”
success: function (data) { //操作成功
alert(data);
},
error: function (result) {//操作失敗
alert("添加失敗");
}
});
return false;
})
</script>
</html>
Java-Controller代碼:
package com.hh.onlinelearning.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
/**
* @author CJCC
*/
@Controller
public class IndexController {
/**
* 跳轉到上傳頁面
* @return
*/
@GetMapping("/cjcc") // 浏覽器位址欄輸入的路徑
public String index2() {
// 項目檔案夾 resource/templates/自定義檔案夾/upload.ftl的路徑
// ftl是freemarker模闆引擎檔案字尾,用其他引擎的如JSP也是一樣的,在配置檔案裡改響應的字尾就好了。
return "management/upload";
}
/**
* 上傳
* @param files
* @return
*/
@PostMapping("/uploadVideo2")// 浏覽器位址欄輸入的路徑
@ResponseBody
public String uploadVideo2(@RequestParam("file")MultipartFile[] files) throws IOException {
/**
* MultipartFile類是用來接收前台傳過來的檔案,常用的方法如下:
* String getContentType() //擷取檔案MIME類型
* InputStream getInputStream() //擷取檔案流
* String getName() //擷取表單中檔案元件的名字
* String getOriginalFilename() //擷取上傳檔案的原名
* long getSize() //擷取檔案的位元組大小,機關byte,除以1024就是kb
* boolean isEmpty() //是否為空
* void transferTo(File dest) //儲存到一個目标檔案中。
*/
for (MultipartFile file : files) { //因為有上傳多個檔案,是以用的是MultipartFile[]數組,是以要周遊數組儲存裡面的每一個檔案
String filePath = "D:/files/"; // 暫時設定儲存在D盤的files目錄下
System.out.println(" 檔案名稱: " + file.getOriginalFilename());
System.out.println(" 檔案大小: " + file.getSize() / 1024D + "Kb");
System.out.println(" 檔案類型: " + file.getContentType());
System.out.println();
//在這裡執行調用檔案儲存的方法....
filePath = filePath + file.getOriginalFilename();
file.transferTo(new File(filePath));
filePath = "";
//其他業務代碼如插入資料庫代碼省略.........
}
return "添加成功";
}
}