1. 程式人生 > >在SpringBoot的環境下,寫上傳檔案的功能,結果沒有獲取到檔案的問題(ServletFileUpload中getItemIterator(request)為空)

在SpringBoot的環境下,寫上傳檔案的功能,結果沒有獲取到檔案的問題(ServletFileUpload中getItemIterator(request)為空)

在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