spring實現檔案上傳和下載 完整方案
阿新 • • 發佈:2019-01-02
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 + "\"不存在");
}
}