1. 程式人生 > >Java-上傳檔案Spring MultipartResolver 或者 ServletFileUpload

Java-上傳檔案Spring MultipartResolver 或者 ServletFileUpload

在Java開發過程中,如果我們想開發上傳功能,那麼有兩種方法可以解決:

  使用Spring框架中的MultipartResolver    使用原生的程式碼ServletFileUpload 下面就簡單介紹下兩種方法如何使用:

1.Spring框架中的MultipartResolver:大體配置和使用程式碼如下

# 將如下xml放入到servlet.xml中: <bean id="multipartResolver"         class="org.springframework.web.multipart.commons.CommonsMultipartResolver">         <property name="maxUploadSize" value="20000000" />    <!-- 上傳限制 20M --> </bean> # 然後在程式碼中這樣寫: @RequestMapping(value = "upload", method = RequestMethod.POST)     public void upload(HttpServletRequest req, HttpServletResponse response,             @RequestParam(value="file", required=true) MultipartFile file,             )throws IOException {        // 1. upload file, 獲取bytes內容        ByteArrayOutputStream bytes = new ByteArrayOutputStream();        IOUtils.copy(file.getInputStream(), bytes);        byte[] byteArray = bytes.toByteArray();} # Html上傳頁面這樣寫: <form name="uploadForm" action="upload" method="POST" enctype="multipart/form-data" >         <label>上傳檔案 </label><br/>         <input type="file" name="file" size="100" style="width:300px;" /> <br />         <input type="submit" name="submit" value="submit"/> </form>

2.原生的程式碼ServletFileUpload:大體配置和使用程式碼如下(HTML同上Spring框架中的MultipartResolver)

@RequestMapping(value = "upload", method = RequestMethod.POST) public void upload(HttpServletRequest req, HttpServletResponse resp             ) throws ServletException, IOException, FileUploadException{         boolean isMultipart = ServletFileUpload.isMultipartContent(req);         HashMap<String, String> request = new HashMap<String, String>();         if (isMultipart) {             DiskFileItemFactory factory = new DiskFileItemFactory(1024 * 1024 * 20, null);             ServletFileUpload upload = new ServletFileUpload(factory);             upload.setHeaderEncoding("UTF-8");             upload.setSizeMax(1024 * 1024 * 20);               List<FileItem> fileItems = upload.parseRequest(req);             Iterator<FileItem> iter = fileItems.iterator();             while (iter.hasNext()) {                 FileItem item = (FileItem) iter.next();                 if (item.isFormField()) {                     String name = item.getFieldName();                     String value = item.getString("UTF-8");                     request.put(name, value);                 } else {                     byte[] filebytes = item.get();                     if (StringUtils.isBlank(item.getName())) {                         continue;                     }                                          request.put(item.getFieldName(), new String(filebyte, "utf-8"));                 }             }         } } 以上是簡單介紹如何使用上傳的兩種方法。這兩種方法既可以單一配置使用,也可以一起配置使用,但是再一 起使用的過程中會出現一個衝突的問題,下面是我再使用過程中遇到的一個問題和解決辦法。

1.問題描述:

如果同時使用了MultipartResolver 和ServletFileUpload,就會導致衝突使ServletFileUpload的方法獲取不到http資料,導致在iter.hasNext()返回false.然後整個迴圈就跳出去了。程式碼如下:

if (isMultipart) {             DiskFileItemFactory factory = new DiskFileItemFactory(1024 * 1024 * 20, null);             ServletFileUpload upload = new ServletFileUpload(factory);             upload.setHeaderEncoding("UTF-8");             upload.setSizeMax(1024 * 1024 * 20);               List<FileItem> fileItems = upload.parseRequest(req);             Iterator<FileItem> iter = fileItems.iterator();             // 這裡獲取不到任何FileItem             while (iter.hasNext()) {                 FileItem item = (FileItem) iter.next();                 if (item.isFormField()) {                     String name = item.getFieldName();                     String value = item.getString("UTF-8");                     request.put(name, value);                 } else {                     byte[] filebytes = item.get();                     if (StringUtils.isBlank(item.getName())) {                         continue;                     }                                          request.put(item.getFieldName(), new String(filebyte, "utf-8"));                 }             }         } } 2.問題產生的原因: 整個問題產生的原因是Spring框架先呼叫了MultipartResolver 來處理http multi-part的請求,這裡http multipart的

請求已經消耗掉。後面又交給ServletFileUpload ,那麼ServletFileUpload 就獲取不到相應的multi-part請求。想快速解

決這個問題,解決方法是加入自己寫的multipartResolver,來單獨處理某些請求。這些請求需要特判。解決程式碼如下:

package example; import javax.servlet.http.HttpServletRequest; import org.springframework.web.multipart.commons.CommonsMultipartResolver;   /**  * @author   */ public class MyMultipartResolver extends CommonsMultipartResolver {     private String excludeUrls;        private String[] excludeUrlArray;          public String getExcludeUrls() {         return excludeUrls;     }       public void setExcludeUrls(String excludeUrls) {         this.excludeUrls = excludeUrls;         this.excludeUrlArray = excludeUrls.split(",");     }         /**      * 這裡是處理Multipart http的方法。如果這個返回值為true,那麼Multipart http body就會MyMultipartResolver 消耗掉.如果這裡返回false      * 那麼就會交給後面的自己寫的處理函式處理例如剛才ServletFileUpload 所在的函式      * @see org.springframework.web.multipart.commons.CommonsMultipartResolver#isMultipart(javax.servlet.http.HttpServletRequest)      */     @Override     public boolean isMultipart(HttpServletRequest request) {         for (String url: excludeUrlArray) {             // 這裡可以自己換判斷             if (request.getRequestURI().contains(url)) {                 return false;             }         }         return super.isMultipart(request);     }       } 然後在springmvc-servlet.xml中這樣寫: <bean id="multipartResolver" class="example.MyMultipartResolver">     <property name="excludeUrls" value="example"/>     <!-- url中帶有example的http請求就不會被multipartResolver先解析--> </bean>

通過上面的辦法就可以解決MultipartResolver 和ServletFileUpload 衝突的問題了。