1. 程式人生 > >Spring Mvc下實現以檔案流方式下載檔案

Spring Mvc下實現以檔案流方式下載檔案

        專案中需要對一個點選事件進行下載操作,同時通過點選事件,已經可以從jsp頁面獲取到需要訪問的URL和下載的檔名(資料庫獲取,jsp頁面顯示)。點選事件JS如下:

function downloadFile(filePath,fileName){
	
	fileName = fileName.substr(0,fileName.lastIndexOf("."));
	$.ajax({
	    async : false,  
	    cache:false,  
	    type: 'get',
	    dataType : "json",  
	    url: RootPath() + "/checkDownload",//請求的action路徑  
	    data:{url:filePath},
	    error: function () {//請求失敗處理函式  
	        alert("下載失敗");
	    },  
	    success:function(json) { //請求成功後處理函式。
	    	var code = json.code;
	    	if(code) {
	    		window.location.href = RootPath()+"/todownload?url="+filePath+"&name="+fileName;
	    	}else {
	    		layer.alert(fileName+' 檔案不存在');  
	    	}
	    }  
	});

}

該ajax呼叫後臺(checkDownload)方法,首先判斷從該url能否獲得指定下載的檔案,如果獲取不到,方法返回引數code=0,頁面彈出“...檔案不存在”。

	@RequestMapping("/checkDownload")
	@ResponseBody
	public Result checkDownload(String url,HttpServletResponse response) {
		Result result = Result.createSuccessResult();
		HttpURLConnection conn = null;
		try {
			URL path = new URL(url);
			conn = (HttpURLConnection) path.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5 * 1000);
			conn.getInputStream();// 通過輸入流獲取資料
		} catch (IOException ex) {
			result.setCode(0);
			ex.printStackTrace();
		}finally {
			if(conn != null) {
				conn.disconnect();
			}
		}
		return result;
	}
        

如果checkDownload方法中能夠正確獲得資源,方法返回引數code=1,ajax成功執行:window.location.href = RootPath()+"/todownload?url="+filePath+"&name="+fileName;   呼叫(todownload)方法,傳入url和name,執行檔案下載。

	@RequestMapping("/todownload")
	@ResponseBody
	public void download(String url, String name, HttpServletResponse response) {
		HttpURLConnection conn = null;
		try {
			File file = new File(url);
			// 取得檔案的字尾名。
			String ext = file.getName().substring(file.getName().lastIndexOf(".") + 1).toLowerCase();
			StringBuffer buffername = new StringBuffer(name);
			String filename = buffername.append(".").append(ext).toString();

			URL path = new URL(url);
			conn = (HttpURLConnection) path.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5 * 1000);
			InputStream fis = conn.getInputStream();// 通過輸入流獲取資料

			byte[] buffer = readInputStream(fis);
			if (null != buffer && buffer.length > 0) {
				// 清空response
				response.reset();
				// 設定response的Header
				response.addHeader("Content-Disposition","attachment;filename="+ new String((filename).getBytes("GBK"),"ISO8859_1"));
				response.addHeader("Content-Length", "" + buffer.length);
				OutputStream toClient = response.getOutputStream();
				response.setContentType("application/octet-stream");
				toClient.write(buffer);
				toClient.flush();
				toClient.close();
			}

		} catch (IOException ex) {
			ex.printStackTrace();
		}finally {
			if(conn != null) {
				conn.disconnect();
			}
		}
	}

    /** 
     * 從輸入流中獲取資料 
     * @param inStream 輸入流 
     * @return 
     * @throws Exception 
     */  
	private byte[] readInputStream(InputStream fis) throws IOException {
		 ByteArrayOutputStream outStream = new ByteArrayOutputStream();  
	        byte[] buffer = new byte[1024];  
	        int len = 0;  
	        while( (len=fis.read(buffer)) != -1 ){  
	            outStream.write(buffer, 0, len);  
	        }  
	        fis.close();  
	        return outStream.toByteArray();
	}