spring實現檔案上傳和下載完整方案
阿新 • • 發佈:2019-02-01
1. 簡介
提供基於spring實現檔案(筆記附件)的上傳和下載的完整方案。方案將檔案上傳,並將檔名稱作為欄位與關聯的筆記繫結在一起,更新筆記在資料庫中的記錄。顯示筆記時,根據筆記所繫結的檔名生成下載路徑,提交給服務端完成下載。2. 檔案上傳
2. 1 前端
在html中插入一個表單用於提交檔案- <formid= "uploadForm">
- <inputtype="file"name="file"id="file"/>
- <inputtype="button"id="upload"value="上傳附件"/>
- </form>
編寫js給button單擊事件,傳送ajax請求,將檔案資料上傳給服務端,服務端返回儲存的真實檔名,將檔名繫結在筆記元素上,在儲存筆記時,將檔名寫入相應筆記的資料庫記錄中。
- //給上傳檔案按鈕繫結事件
- $("#upload").click(uploadFile);
[javascript] view plain copy
- function uploadFile(){
- //獲得上傳檔案
- $.ajax({
- url: 'file/upload.do',
- type: 'POST',
- cache: false,
- data: new FormData($('#uploadForm')[0]),
- processData: false,
- contentType: false,
- success:function(result){
- var $checkedLi = $("#note_list li a.checked").parent();
- $checkedLi.data("attachment",result.data);
- alert("上傳成功"+result.data);
- }
- });
- }
1. 2 後端
採用CommonsMultipartResolver,需要匯入commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar,sc是ServletContext的引用,用實現ServletContextAware介面的方式獲得。- public JsonResult upload(HttpServletRequest request,HttpServletResponse response) throws Exception{
- JsonResult result = new JsonResult();
- try{
- request.setCharacterEncoding("utf-8");
- //建立一個通用的多部分解析器
- CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(sc);
- //判斷 request 是否有檔案上傳,即多部分請求
- if(multipartResolver.isMultipart(request)){
- //轉換成多部分request
- MultipartHttpServletRequest multiRequest =
- multipartResolver.resolveMultipart(request);
- //取得request中的所有檔名
- Iterator<String> iter = multiRequest.getFileNames();
- while(iter.hasNext()){
- //取得上傳檔案
- MultipartFile file = multiRequest.getFile(iter.next());
- if(file != null){
- //取得當前上傳檔案的檔名稱
- String myFileName = file.getOriginalFilename();
- //如果名稱不為“”,說明該檔案存在,否則說明該檔案不存在
- if(myFileName.trim() !=""){
- //重新命名上傳後的檔名
- String fileName = file.getOriginalFilename();
- //定義上傳路徑
- String dirPath = sc.getRealPath("/WEB-INF/files/");
- File dir = new File(dirPath);
- if(!dir.exists()){
- dir.mkdirs();
- }
- File localFile = new File(dir, NoteUtil.creatId().substring(30)+"-"+fileName);
- file.transferTo(localFile);
- //結果繫結檔案路徑
- result.setStatus(0);
- result.setData(localFile.getName());
- result.setMsg("上傳成功");
- }
- }
- }
- }
- }catch(Exception e){
- e.printStackTrace();
- throw e;
- }
- result.setStatus(1);
- return result;
- }
2. 檔案下載
2. 1 前端
由於get請求存在中文編碼異常的問題,所以採用post請求,首先獲取元素中繫結的檔名,生成一個表單 [javascript] view plain copy- if(attachment!=null){
- var form_str = '<form action="file/download.do" method="post">'+
- '<input type="hidden" name="fileName" value="'+attachment+'"></input>'+
- '<input type="submit" value="下載附件"></input>'+
- '</form>';
- $("#download_attachment").html(form_str);
- }
2. 2 後端
後端需要解決中文檔名無法正常顯示的問題,採用ISO8859-1字符集- publicvoid download(HttpServletResponse response, String fileName) throws Exception{
- System.out.println(fileName);
- String filePath = "/WEB-INF/files/"+fileName;
- String fileFullPath = sc.getRealPath(filePath);
- File file = new File(fileFullPath);
- if(file.exists()){
- //重置response
- response.reset();
- response.setCharacterEncoding("utf-8");
- response.setContentType("text/html;charset=utf-8");
- //設定http頭資訊的內容
- / response.addHeader("Content-Disposition", "attachment;filename=\""+fileName+"\"");
- //解決中文檔名顯示問題
- response.addHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("gb2312"),"ISO8859-1"));
- //設定檔案長度
- int fileLength = (int)file.length();
- response.setContentLength(fileLength);
- if(fileLength!=0){
- InputStream inStream = new FileInputStream(file);
- byte[] buf = newbyte[4096];
- //建立輸出流
- ServletOutputStream servletOS = response.getOutputStream();
- int readLength;
- //讀取檔案內容並寫入到response的輸出流當中
- while((readLength = inStream.read(buf))!=-1){
- servletOS.write(buf, 0, readLength);
- }
- //關閉輸入流
- inStream.close();
- //重新整理輸出流緩衝
- servletOS.flush();
- //關閉輸出流
- servletOS.close();
- }
- }else{
- response.setContentType("text/html;charset=utf-8");
- PrintWriter out = response.getWriter();
- out.println("檔案\""+fileName + "\"不存在");
- }
- }