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

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

1. 簡介

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

2. 檔案上傳

2. 1 前端

在html中插入一個表單用於提交檔案
<form id= "uploadForm">
	<input type="file" name="file" id="file"/>
        <input type="button" id="upload" value="上傳附件"/>
</form>

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

		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請求,首先獲取元素中繫結的檔名,生成一個表單
			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字符集
	public void 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 = new byte[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 + "\"不存在");
		}
	}