遇到問題-----uploadify上傳檔案ServletFileUpload.isMultipartContent(request)為false
阿新 • • 發佈:2019-01-26
現象和問題
我們使用的是SpirngMVC框架,然後在其中使用uploadify上傳檔案。
上傳程式碼為:
//初始化圖片上傳容器 var initImageUploader = function () { var selfId = $('#icon_upload_uploader').attr("id"); var $input = $('#icon_upload_filePath'); console.log($input); $('#icon_upload_uploader').uploadifive({ 'height': 300, 'width': 300, 'uploadScript': '/upload;_sid=${pageContext.session.id}', 'fileSizeLimit': '1200KB', 'buttonClass': 'upload-image img-thumbnail', 'buttonText': '', 'multi': false, 'onInit': function(instance) { updateUploadButtonBackground(selfId, $input.val()); }, 'removeCompleted': true, 'onUploadComplete': function (file, data, response) { data = JSON.parse(data); if (data.code) { var url = '${hostname}' + data.result; $input.val(url); updateUploadButtonBackground(selfId, url); } } }); }; initImageUploader();
接收程式碼為:
package com.test.web.controller; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.test.util.AjaxResult; /** * 通用的上傳(儲存到本地伺服器) * */ @Controller public class UploadController { private final Logger logger = LoggerFactory.getLogger(getClass().getName()); /** * 上傳到伺服器,檔名稱隨機生成(基本可以保證不重複) * * @param request * @param response * @return AjaxResult 儲存的檔案的相對路徑 * @throws IOException */ @RequestMapping("/upload") @ResponseBody public AjaxResult upload(HttpServletRequest request, HttpServletResponse response) throws IOException { try { //獲取檔案儲存路徑 String path = request.getRealPath("/upload"); String fileNameResult =""; // 判斷enctype屬性是否為multipart/form-data boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (!isMultipart) throw new IllegalArgumentException( "上傳內容不是有效的multipart/form-data型別."); // Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); // Parse the request List<?> items = upload.parseRequest(request); Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.isFormField()) { // 如果是普通表單欄位 String name = item.getFieldName(); String value = item.getString(); // ... } else { // 如果是檔案欄位 String fieldName = item.getFieldName(); String fileName = item.getName(); String contentType = item.getContentType(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); String fileExt = fileName.substring(fileName.lastIndexOf('.')); String fileNameNew =getFileNameNew()+fileExt; fileNameResult=fileNameNew; //儲存到本地 InputStream uploadedStream = item.getInputStream(); savePic(path,uploadedStream,fileNameNew); uploadedStream.close(); } } return AjaxResult.resultSuccess("/upload/"+fileNameResult); } catch (FileUploadException e) { logger.warn(e.getMessage(), e); return AjaxResult.resultError(e.getMessage()); } } private void savePic(String path,InputStream inputStream, String fileName) { OutputStream os = null; try { // 2、儲存到臨時檔案 // 1K的資料緩衝 byte[] bs = new byte[1024]; // 讀取到的資料長度 int len; // 輸出的檔案流儲存到本地檔案 File tempFile = new File(path); if (!tempFile.exists()) { tempFile.mkdirs(); } os = new FileOutputStream(tempFile.getPath() + File.separator + fileName); // 開始讀取 while ((len = inputStream.read(bs)) != -1) { os.write(bs, 0, len); } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { // 完畢,關閉所有連結 try { os.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } private String getFileNameNew() { SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS"); return fmt.format(new Date()); } }
遇到問題,第一次上傳圖片成功之後,第二次上傳圖片時 報錯 上傳內容不是有效的multipart/form-data型別。
也就是說ServletFileUpload.isMultipartContent(request)為false。
request中不含有檔案表單資料。
經過排查 發現原因是 寫入檔案時 建立的 路徑與路由路徑衝突導致的。
細心的讀者可以發現 uploadify中設定的 上傳到 路由的路徑為:
'uploadScript': '/upload;_sid=${pageContext.session.id}',
也就是
/upload
但是在儲存 圖片到 本地伺服器時 ,我們儲存的路徑也是/upload。
//獲取檔案儲存路徑
String path = request.getRealPath("/upload");
第一次上傳圖片時,會建立upload資料夾。
訪問圖片使用 http://127.0.0.1/upload/圖片名.png 訪問。
當第二次 圖片上傳時,有兩個 /upload 路由請求連結。
所以進到 接收檔案的路由 /upload 時,已經不是含有檔案的request了。
解決方法
儲存檔案的路徑不使用 與 路由同名路徑。 如果已經存在同名靜態資源訪問路徑,則需要刪除同名靜態資原始檔夾 或者 修改路由路徑。
例如 我這裡把 儲存圖片的地址修改為/uploadfile。