1. 程式人生 > >spring實現檔案上傳和下載完整方案

spring實現檔案上傳和下載完整方案

1. 簡介

提供基於spring實現檔案(筆記附件)的上傳和下載的完整方案。方案將檔案上傳,並將檔名稱作為欄位與關聯的筆記繫結在一起,更新筆記在資料庫中的記錄。顯示筆記時,根據筆記所繫結的檔名生成下載路徑,提交給服務端完成下載。

2. 檔案上傳

2. 1 前端

在html中插入一個表單用於提交檔案
  1. <formid"uploadForm">
  2.     <inputtype="file"name="file"id="file"/>
  3.         <inputtype="button"id="upload"value="上傳附件"/>
  4. </form>

編寫js給button單擊事件,傳送ajax請求,將檔案資料上傳給服務端,服務端返回儲存的真實檔名,將檔名繫結在筆記元素上,在儲存筆記時,將檔名寫入相應筆記的資料庫記錄中。
[javascript] view plain copy
  1. //給上傳檔案按鈕繫結事件
  2.             $("#upload").click(uploadFile);  

[javascript] view plain copy
  1. function uploadFile(){  
  2.     //獲得上傳檔案
  3.     $.ajax({  
  4.         url: 'file/upload.do',  
  5.         type: 'POST',  
  6.         cache: false,  
  7.         data: new FormData($('#uploadForm')[0]),  
  8.         processData: false,  
  9.         contentType: false,  
  10.         success:function(result){  
  11.             var $checkedLi = $("#note_list li a.checked").parent();  
  12.             $checkedLi.data("attachment",result.data);  
  13.             alert("上傳成功"+result.data);  
  14.         }  
  15.     });   
  16. }  

1. 2 後端

採用CommonsMultipartResolver,需要匯入commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar,sc是ServletContext的引用,用實現ServletContextAware介面的方式獲得。
  1. public JsonResult upload(HttpServletRequest request,HttpServletResponse response) throws Exception{  
  2.     JsonResult result = new JsonResult();  
  3.     try{  
  4.         request.setCharacterEncoding("utf-8");  
  5.         //建立一個通用的多部分解析器
  6.         CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(sc);  
  7.         //判斷 request 是否有檔案上傳,即多部分請求
  8.         if(multipartResolver.isMultipart(request)){  
  9.             //轉換成多部分request  
  10.             MultipartHttpServletRequest multiRequest =           
  11.                     multipartResolver.resolveMultipart(request);  
  12.             //取得request中的所有檔名
  13.             Iterator<String> iter = multiRequest.getFileNames();  
  14.             while(iter.hasNext()){  
  15.                 //取得上傳檔案
  16.                 MultipartFile file = multiRequest.getFile(iter.next());  
  17.                 if(file != null){  
  18.                     //取得當前上傳檔案的檔名稱
  19.                     String myFileName = file.getOriginalFilename();  
  20.                     //如果名稱不為“”,說明該檔案存在,否則說明該檔案不存在
  21.                     if(myFileName.trim() !=""){  
  22.                         //重新命名上傳後的檔名
  23.                         String fileName = file.getOriginalFilename();  
  24.                         //定義上傳路徑
  25.                         String dirPath = sc.getRealPath("/WEB-INF/files/");  
  26.                         File dir = new File(dirPath);  
  27.                         if(!dir.exists()){  
  28.                             dir.mkdirs();  
  29.                         }  
  30.                         File localFile = new File(dir, NoteUtil.creatId().substring(30)+"-"+fileName);  
  31.                         file.transferTo(localFile);  
  32.                         //結果繫結檔案路徑
  33.                         result.setStatus(0);  
  34.                         result.setData(localFile.getName());  
  35.                         result.setMsg("上傳成功");  
  36.                     }  
  37.                 }  
  38.             }  
  39.         }  
  40.     }catch(Exception e){  
  41.         e.printStackTrace();  
  42.         throw e;  
  43.     }  
  44.     result.setStatus(1);  
  45.     return result;  
  46. }  

2. 檔案下載

2. 1 前端

由於get請求存在中文編碼異常的問題,所以採用post請求,首先獲取元素中繫結的檔名,生成一個表單 [javascript] view plain copy
  1. if(attachment!=null){  
  2.     var form_str = '<form action="file/download.do" method="post">'+  
  3.                         '<input type="hidden" name="fileName" value="'+attachment+'"></input>'+  
  4.                         '<input type="submit" value="下載附件"></input>'+  
  5.                     '</form>';  
  6.     $("#download_attachment").html(form_str);  
  7. }  

2. 2 後端

後端需要解決中文檔名無法正常顯示的問題,採用ISO8859-1字符集
  1. publicvoid download(HttpServletResponse response, String fileName) throws Exception{  
  2.     System.out.println(fileName);  
  3.     String filePath = "/WEB-INF/files/"+fileName;  
  4.     String fileFullPath = sc.getRealPath(filePath);  
  5.     File file = new File(fileFullPath);  
  6.     if(file.exists()){  
  7.         //重置response
  8.         response.reset();  
  9.         response.setCharacterEncoding("utf-8");  
  10.         response.setContentType("text/html;charset=utf-8");  
  11.         //設定http頭資訊的內容
  12. /           response.addHeader("Content-Disposition""attachment;filename=\""+fileName+"\"");  
  13.         //解決中文檔名顯示問題
  14.         response.addHeader("Content-Disposition""attachment;filename="+new String(fileName.getBytes("gb2312"),"ISO8859-1"));  
  15.         //設定檔案長度
  16.         int fileLength = (int)file.length();  
  17.         response.setContentLength(fileLength);  
  18.         if(fileLength!=0){  
  19.             InputStream inStream = new FileInputStream(file);  
  20.             byte[] buf = newbyte[4096];  
  21.             //建立輸出流
  22.             ServletOutputStream servletOS = response.getOutputStream();  
  23.             int readLength;  
  24.             //讀取檔案內容並寫入到response的輸出流當中
  25.             while((readLength = inStream.read(buf))!=-1){  
  26.                 servletOS.write(buf, 0, readLength);  
  27.             }  
  28.             //關閉輸入流
  29.             inStream.close();  
  30.             //重新整理輸出流緩衝
  31.             servletOS.flush();  
  32.             //關閉輸出流
  33.             servletOS.close();  
  34.         }  
  35.     }else{  
  36.         response.setContentType("text/html;charset=utf-8");  
  37.         PrintWriter out = response.getWriter();  
  38.         out.println("檔案\""+fileName + "\"不存在");  
  39.     }  
  40. }