在SpringBoot的環境下,寫上傳檔案的功能,結果沒有獲取到檔案的問題(ServletFileUpload中getItemIterator(request)為空)
阿新 • • 發佈:2019-01-09
在SpringBoot的環境下,寫上傳檔案的功能,結果沒有獲取到檔案的問題:
情況一:
使用Apache Commons FileUpload 元件上傳檔案時總是返回null,multipart/form-data型別檔案的接收。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Hello World!</title> </head> <body> <form method="POST" enctype="multipart/form-data" action="/upload"> <p>檔案1:<input type="text" name="id" /></p> <!-- <p>檔案2:<input type="text" name="name" /></p> <p>檔案3:<input type="file" name="file" /></p> --> <p><input type="submit" value="上傳" /></p> </form> </body> </html>
情況二:
使用百度的外掛webuplader,帶css,js,swf檔案,前端如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>上傳檔案</title> <link rel="stylesheet" type="text/css" href="/assets/dist/webuploader/webuploader.css"> <script src="/assets/dist/webuploader/webuploader.js"></script> <script src="/js/Uploader.js"></script> </head> <div id="UploaderDialog" style="display: none;height: 592px"> <div style="background-color: white; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px;"> <div id="uploader" class="wu-example"> <!--用來存放檔案資訊--> <div id="fileList" class="uploader-list"></div> <div class="btns"> <div id="picker" style="padding:0 8px 0 0">選擇檔案</div> <!-- <button id="picker" class="btn btn-default" style="width:75px;height:33px;margin:0 5px 5px 0">選擇檔案</button>--> <button id="ctlBtn" class="btn btn-default" style="width:75px;height:33px;margin:2px 0 5px 0">開始上傳</button> <button id="cancleBtn" class="btn btn-default" style="width:75px;height:33px;margin:2px 0 5px 5px">取消上傳</button> </div> </div> </div> </div> <body> <script type="text/javascript"> $(function() { $("#UploaderDialog").dialog({ autoOpen : false, // 是否自動彈出視窗 modal : true, // 設定為模態對話方塊 resizable : true, width : 550, //彈出框寬度 height : 205, //彈出框高度 title : "上傳檔案" //彈出框標題 }); $("#back-button").click(function() { $("#UploaderDialog").dialog("close"); }); }); </script> </body> </html>
後臺接收檔案的處理方式都是一樣的:
@RequestMapping("/uploadingfiles") public void uploadingfiles(HttpServletRequest request, HttpServletResponse response){ DataSourceRouter.routerTo("222222"); response.setHeader("Access-Control-Allow-Origin", "*"); String filename=null; String file_id = null; UPloadFile ups=new UPloadFile(); try{ ServletFileUpload upload = new ServletFileUpload();//檔案上傳解析器 upload.setHeaderEncoding("utf-8");// 防止中文檔名亂碼 FileItemIterator iter = upload.getItemIterator(request); while(iter.hasNext()) { FileItemStream item = iter.next(); InputStream input = null; System.out.println("121212121212121"); try{ input=item.openStream(); if(!item.isFormField()){ if(input.available()>0) { filename = item.getFieldName(); System.out.println(filename); int xlh = phdyService.getMaxXlh(); ups = phdyService.uploadfiledj(xlh, input, filename); } }else{ if("id".equals(item.getFieldName())){ file_id = Streams.asString(input, "utf-8"); } } } catch (IOException e) { e.printStackTrace(); }finally { IOUtil.close(input); } } } catch (FileUploadException e) { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); }finally{ if(ups==null){ ResponseResult rr = ResponseResult.defaultErr("上傳失敗"); rr.write(response); }else{ System.out.println(ups); System.out.println(ups.getFilename()); System.out.println(ups.getWJscsj()); System.out.println(ups.getWJscsj()); // ResponseBuilder builder=new ResponseBuilder(); // builder.writeJsonResponse(response,ups); ResponseResult.defaultOK(ups).write(response); } } }
其中FileItemIterator iter = upload.getItemIterator(request);這段獲取的是空值。
問題的原因是:
spring-boot自帶的org.springframework.web.multipart.MultipartFile
和Multipart產生衝突,如果同時使用了MultipartResolver 和ServletFileUpload,就會在iter.hasNext()返回false.然後整個迴圈就跳出去了。整個問題產生的原因是Spring框架先呼叫了MultipartResolver 來處理http multi-part的請求。這裡http multipart的請求已經消耗掉。後面又交給ServletFileUpload ,那麼ServletFileUpload 就獲取不到相應的multi-part請求。因此將multipartResolve配置去除,問題就解決了。
在使用ServletFileUpload時需要關閉Spring Boot的預設配置 ,所以在配置檔案中新增
spring.http.multipart.enabled=false