1. 程式人生 > >JAVA檔案下載

JAVA檔案下載

1.首先在html頁面使用a標籤來連線到需要下載的資源,資源是放在WebContent下的download目錄下的

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	
	<h2>使用伺服器端編碼的方式實現檔案下載</h2>
	<a href="/WEB14/downloadServlet?fileName=a.flv">點選下載a.flv視訊</a><br/>
	<a href="/WEB14/downloadServlet?fileName=b.jpg">點選下載b.jpg圖片</a><br/>
	<a href="/WEB14/downloadServlet?fileName=c.mp3">點選下載c.mp3音訊</a><br/>
	
</body>
</html>

2.在DownloadServlet中告訴客戶端檔案不用解析直接下載

package com.content;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//獲得要下載的檔案的名稱
		String fileName = request.getParameter("fileName");
		
		//要下載的檔案的型別----客戶端通過檔案的MIME型別來區別檔案型別(這個可以不用寫)
		//response.setContentType(this.getServletContext().getMimeType(fileName));

		//告訴客戶端該檔案不是直接解析,而是下載(後面拼上檔案的名字)
		response.setHeader("Content-Disposition","attachment;filename="+fileName);
		
		//獲取檔案的絕對路徑
		String path = this.getServletContext().getRealPath("download/"+fileName);

		//獲得該檔案的輸入流
		InputStream in = new FileInputStream(path);
		
		//獲得輸出流---通過response獲得的輸出流,用於向客戶端寫內容
		ServletOutputStream out = response.getOutputStream();
		
		//檔案拷貝(檔案下載其實就是檔案拷貝)
		int len = 0;
		byte[] buffer = new byte[1024];
		while((len=in.read(buffer))>0) {
			out.write(buffer,0,len);
		}
		in.close();
		out.close();//這個可以不寫,因為是由response建立的輸出流物件,tomcat容器會幫我們關上
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		doGet(request, response);
	}

}

3.上面的DownloadServlet無法下載中文名的檔案,需要優化編碼

package com.content;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sun.misc.BASE64Encoder;

@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲得要下載的檔案的名稱,這裡獲得的要是中文檔名會產生亂碼,需要處理
        String fileName = request.getParameter("fileName");
        
        //解決中文亂碼問題,但是後續編碼依舊會有問題
        fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
        
        //要下載的檔案的型別----客戶端通過檔案的MIME型別來區別檔案型別(這個可以不用寫)
        //response.setContentType(this.getServletContext().getMimeType(fileName));

        //獲得請求頭中的User-Agent,這段程式碼不許要記憶,要用時直接拿來用就行了
        String agent = request.getHeader("User-Agent");
        String chineseFileName = "";
        //根據不同瀏覽器進行不同的編碼
        if(agent.contains("MSIE")) {
            //IE瀏覽器
            chineseFileName = URLEncoder.encode(fileName, "utf-8");
            chineseFileName = chineseFileName.replace("+", " ");
        }else if(agent.contains("Firefox")) {
            //火狐瀏覽器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            chineseFileName = "=?utf-8?B?"+base64Encoder.encode(fileName.getBytes("utf-8"))+"?=";
        }else {
            chineseFileName = URLEncoder.encode(fileName, "utf-8");
        }

        //告訴客戶端該檔案不是直接解析,而是下載(後面拼上檔案的名字),這裡的fileName客戶端用預設的編碼解析,所以我們需要用對應客戶端的解碼形式來進行編碼
        response.setHeader("Content-Disposition","attachment;filename="+chineseFileName);
        
        //獲取檔案的絕對路徑
        String path = this.getServletContext().getRealPath("download/"+fileName);

        //獲得該檔案的輸入流
        InputStream in = new FileInputStream(path);
        
        //獲得輸出流---通過response獲得的輸出流,用於向客戶端寫內容
        ServletOutputStream out = response.getOutputStream();
        
        //檔案拷貝(檔案下載其實就是檔案拷貝)
        int len = 0;
        byte[] buffer = new byte[1024];
        while((len=in.read(buffer))>0) {
            out.write(buffer,0,len);
        }
        in.close();
        out.close();//這個可以不寫,因為是由response建立的輸出流物件,web容器會幫我們關上
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        doGet(request, response);
    }

}