1. 程式人生 > >JavaWeb筆記-22-檔案下載

JavaWeb筆記-22-檔案下載

1、檔案下載


下載:向客戶端響應位元組資料。(原來響應的是html的字元資料)

做法:把一個檔案變成位元組陣列,使用response.getOutputStream();來響應給瀏覽器

要求:兩個頭、一個流
    Content-Type頭:傳遞給客戶端的MIME型別
        使用 this.ServletContext.getMimeType("檔案路徑名")方法,得到MIME型別! 傳參為檔案路徑名

    Content-Disposition頭:設定是否彈出下載框。 
        預設值為inline,表示在瀏覽器視窗開啟
        設定值為:attachment;filename=xxx;  表示彈出現在框
            filename=後面跟隨的是顯示在下載框中的檔名稱!

    流:要下載的檔案資料
        new一個輸入流即可

下載步驟:
    1)得到兩個頭
        Content-Type頭:
                使用 this.ServletContext.getMimeType("檔案路徑名")方法,得到MIME型別! 傳參為檔案路徑名
        Content-Disposition頭 (設定為彈窗下載,彈窗中顯示處理過編碼的名稱) 
                String contentDisposition = "attachment;filename="+framname;
    2)得到資料流
        FileInputStream input = new FileInputStream(filename); 

    3)將兩個頭設定給響應
        response.setHeader("Content-Type", contentType);
        response.setHeader("Content-Disposition", contentDisposition);

    4)將流繫結客戶端地址(流往到客戶端)
        ServletOutputStream output = response.getOutputStream();

    5)把輸入流中的資料寫入到輸出流中
        IOUtils.copy(input, output);

下載細節
    亂碼問題:當下載框顯示中文名稱時,會出現亂碼
        FireFox:Base64編碼
        其他瀏覽器:URL編碼。

通用解決方案:
filename = new String("需要處理的檔名".getBytes("GBK"),"IOS-8859-1");

上述方案存在個別特殊字元不能正確顯示
解決:使用方法filenameEncoding   

2、程式碼演示:


public class Download1Servlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /*
         * 下載歌曲:    
         * 兩個頭、一個流
         * 1.Content-Type
         * 2.Content-Disposition
         * 3.流:檔案資料流
         */
//得到Content-Type頭 //得到檔案路徑名 String filename = "C:/Users/11316/Music/思疆調.mp3"; //處理檔名亂碼問題 // String newfilename = new String("思疆調.mp3".getBytes("GBK"),"ISO-8859-1"); String framname = filenameEncoding("思疆調.mp3",request); //通過檔案路徑名稱獲取MIME型別 String contentType = this
.getServletContext().getMimeType(filename); //得到 Content-Disposition頭 (設定為彈窗下載,彈窗中顯示處理過編碼的名稱) String contentDisposition = "attachment;filename="+framname; //流 通過檔案路徑名的得到資料流 FileInputStream input = new FileInputStream(filename); //為響應設定兩個頭: Content-Type、Content-Disposition response.setHeader("Content-Type", contentType); response.setHeader("Content-Disposition", contentDisposition); //獲取綁定了客戶端的流(流往到客戶端) ServletOutputStream output = response.getOutputStream(); //把輸入流中的資料寫入到輸出流中 IOUtils.copy(input, output); //關閉流 input.close(); } // 用來對下載的檔名稱進行編碼的! 根據不同瀏覽器不同編碼處理 public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException { String agent = request.getHeader("User-Agent"); //獲取瀏覽器 if (agent.contains("Firefox")) { BASE64Encoder base64Encoder = new BASE64Encoder(); filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else if(agent.contains("MSIE")) { filename = URLEncoder.encode(filename, "utf-8"); } else { filename = URLEncoder.encode(filename, "utf-8"); } return filename; } }

知識點: enctype屬性
這裡寫圖片描述