本篇介紹如何使用jQuery.ajax()
來非同步上傳檔案至Spring MVC的Controller。
傳送檔案的jsp頁面file-upload.jsp
。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
</head>
<body>
<div>
<form id="myForm">
<input type="file" name="file" id="file"/>
<button type="submit">上傳檔案</button>
</form>
</div>
</body>
<script>
$(function(){
$("#myForm").submit(function(e){
e.preventDefault(); // 停止觸發submit
console.log("upload");
var formData = new FormData($("#myForm")[0]); // 使用FormData包裝form表單來傳輸資料
$.ajax({
type: "POST",
url: "upload",
data:formData,
cache:false, // 不需要cache
processData: false, // jQuery預設會把data轉為query String, 所以要停用
contentType: false, // jQuery預設contentType為'application/x-www-form-urlencoded; charset=UTF-8', 且不用自己設定為'multipart/form-data'
dataType: 'text',
success: function (data){
console.log(data);
}
});
});
});
</script>
</html>
contentType
務必要設為false,不要自己設為"multipart/form-data"
,因為如果自己設定為"multipart/form-data"
會缺少boundary參數,Spring MVC在處理時會出現下面錯誤。
org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
Spring MVC的配置檔設定,因為要上傳檔案記得要設定MultipartResolver。因為這邊使用CommonsMultipartResolver
,所以必須將依賴的Apache Commons FileUpload的函式庫加入專案的Libraries。
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven /><!-- 啟用Spring MVC annotation配置,例如@Controller -->
<context:component-scan base-package="idv.matt.controller"/> <!-- 透過掃描@Component來註冊Bean -->
<!-- MultipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="20971520" /> <!-- 20MB -->
<property name="maxUploadSizePerFile" value="5242880"/> <!-- 5MB -->
<property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
<property name="defaultEncoding" value="UTF-8" />
</bean>
</beans>
用來接收上傳檔案的MyController
,此類別掛有@RestController
所以會被配置檔設定的<context:component-scan/>
掃描並註冊於Spring容器。
MyController.java
package idv.matt.controller;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
public class MyController {
@PostMapping(value="upload", produces = MediaType.TEXT_PLAIN_VALUE)
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
if (!file.getOriginalFilename().isEmpty()) {
BufferedOutputStream outputStream = new BufferedOutputStream(
new FileOutputStream(
new File("D:/", file.getOriginalFilename()))); // 上傳檔案位置為D:\
outputStream.write(file.getBytes());
outputStream.flush();
outputStream.close();
}else{
return "fail";
}
return "success";
}
}
注意@RequestParam
的值必須等於表單中<input type="file" />
的name
屬性一致,範例中為"file"。如果不一致會出現錯誤HTTP Status 400 Bad Request錯誤如下。
HTTP Status 400 - Required request part 'xxx' is not present
完成以上設定便可以透過Ajax來上傳檔案了。
參考:
沒有留言:
張貼留言