參考文章:
- https:///questions/36005436/the-request-was-rejected-because-no-multipart-boundary-was-found-in-springboot
- http:///sUur
問題:
- 多文件上傳 攜帶參數(shù)獲取為 null
- Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
解決方案:
先直接上代碼,等會再說問題的原因。
前端:
表單上傳
<form id="upmore">
<input type="file" name="fileList" value="請選擇文件" multiple id="file1">
<input type="file" name="fileList" value="請選擇文件" multiple id="file2">
<input type="text" name="content" value="hahahahahahaha" multiple id="content">
<input type="button" onclick="doUpload2()" value="上傳2">
</form>
<script src="../js/jquery-3.4.1.min.js"></script>
<script>
function doUpload2() {
let form = new FormData($("#upmore")[0])
console.log(form.get("content"))
var settings = {
"url": "http://localhost/tps/scp/feedback/commit",
"method": "POST",
"timeout": 0,
"headers": {
"token": "5f1b9ff0e4b08b8a8fa3d106374864651320e976dfef314722b1a9529dfcdc828e"
},
"processData": false,
"mimeType": "multipart/form-data",
"contentType": false,
"data": form
};
$.ajax(settings).done(function (response) {
console.log(response);
});
}
</script>
后端:
@Configuration
public class BeanConfig {
@Bean(name = "multipartResolver")
public MultipartResolver multipartResolver(){
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
resolver.setResolveLazily(true);//resolveLazily屬性啟用是為了推遲文件解析,以在在UploadAction中捕獲文件大小異常
resolver.setMaxInMemorySize(40960);
resolver.setMaxUploadSize(50*1024*1024);//上傳文件大小 50M 50*1024*1024
return resolver;
}
}
@PostMapping("/scp/feedback/commit")
public R commit(@RequestParam(required = false) List<MultipartFile> fileList, String content,
HttpServletRequest request) throws FileUploadException {
System.out.println(fileList.size() + " " + content);
// ......
return null;
}
分析
接口寫好之后,我通常會直接使用postman先行測試,隨后再拿到前端使用。如圖最基本的測試,是通過了的。
接著,我將postman生成的ajax代碼拷貝了一份,直接拿到了前端使用。出乎意料之外的事情發(fā)生,居然報錯了:
The request was rejected because no multipart boundary was found in springboot 翻譯成中文就是該請求被拒絕,因為在springboot中找不到多部分邊界
隨之我有測試了幾次,postman中請求可以成功,但是在瀏覽器中接口就會報錯。
通過postman生成標準接口的請求代碼,這非常方便。(小技巧) 在stackoverflow的一篇文章中,我找到了解決方案,使用postman生成上傳文件的ajax代碼時,不需要手動填寫content-type請求頭,postman會自動我們決定。隨后,生成的正確代碼也確實測試通過了。
接著在使用FormData的方式上傳文件時,會出現(xiàn)攜帶的參數(shù)在后端獲取為null值的情況。最終在一位網(wǎng)友的博客中找到了解決方案。博客中也將原因闡述的很清楚:
產(chǎn)生的原因就是對于multipart/formdata的請求,SpringMVC沒有提供默認解析器,導致請求無法正確的被解析。需要我們自己提供一個org.springframework.web.multipart.MultipartResolver解析器。
雖然說的是SpringMVC,但是對于SpringBoot來說同樣適用。在上面的代碼中,通過在Java config 中配置bean的方式注入了MultipartResolver解析器。
到此,兩個問題全部被解決。
事實上,在之前的代碼編寫過程中,處理文件上傳相關(guān)的業(yè)務(wù),我的做法都是將文件與參數(shù)進行分開處理的,對于小文件來說,這可能是不錯的做法,可以提高接口的效率。但是對于大文件來說,接口效率本就不高,將請求參數(shù)與文件一并傳遞,倘若接口請求失敗,可以即時刪除占用磁盤空間的文件,減少數(shù)據(jù)冗余。
|