jsp實現文件下載,out = pageContext.pushBody();out.close();不用寫到jsp中


測試jsp:

<%@ page contentType="text/html; charset=gbk" %>
<%
try{
 com.enfo.intrust.web.DocumentFile file = new com.enfo.intrust.web.DocumentFile(pageContext);
 String file_name = "d:/中國人.txt";
 String name = "中國人.txt";
 file.downloadFile(file_name,name);
}catch(Exception e){
 throw new Exception(e.getMessage());
}
%>

 

調用的下載類:

package com.enfo.intrust.web;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;

public class DocumentFile {
    private PageContext pageContext;
    public DocumentFile() {}
    public DocumentFile(PageContext in_pageContext) {
        try {
            pageContext = in_pageContext;
        } catch (Exception e) {
            pageContext = null;
        }
    }
    
    private String Encode(String in) {
        try {
            return new String(in.getBytes("GBK"), "ISO-8859-1");
        } catch (Exception e) {
            return in;
        }
    }

    /**
     * @param strFile 文件路徑
     * @param name 文件名,包含后綴
     * */
    public void downloadFile(String filePath, String fileName)throws Exception {
        java.io.File file = new java.io.File(filePath);
        if (!file.exists()) throw new Exception("file not exist");
        /**
         *取消JSP默認的輸出流:javax.servlet.jsp.JspWriter
         */
        JspWriter out = pageContext.getOut();
        out.clear();
        /**
         * Websphere發布環境中,不能要下面這一行代碼
         * 主要是Weblogic或Websphere發布環境中問題,與tomcat不同
         * 此處pushBody會將out引用一個新對象ContextBody的實例,ContextBody是JspWriter的子類
         */
        //out = pageContext.pushBody();

        /**
         * response.getWriter()取得的是java.io.PrintWriter,輸出以字符為單位;
         * response.getOutputStream()取得的是javax.servlet.serlvetoutputstream,輸出以字節為單位;
         * 采用response的輸出流:ServletOutputStream
         * 從本地文件的輸入流讀取數據通過這個字節輸出流輸出
         */
        HttpServletResponse response = (HttpServletResponse) (pageContext.getResponse());
        response.reset();    
        response.setContentType("application/octet-stream");
        response.addHeader("Content-disposition", Encode("attachment;filename=" + fileName));
        DataInputStream dis = null;
        OutputStream os = null;//jsp不用默認的out內置對象,而采用這個字節輸出流
        try {
            dis = new DataInputStream(new FileInputStream(file));
            os = response.getOutputStream();
            byte[] buf = new byte[1024];
            int curLen=0;
            System.out.println("start to download:"+fileName);
            while((curLen=dis.read(buf))>=0){
                os.write(buf, 0, curLen);
                os.flush();
            }
            System.out.println("download success");
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("download error");
        } finally {
            if(os != null)
                os.close();
            if(dis != null)
                dis.close();
            if(out != null)
            {
                 //out.close();
                /**
                 *jsp引擎中,在每個jsp結束后都會自動釋放掉jsp所有內置對象,包括out;如果這里手動人為的把out這個jsp內置對象關閉了,
                 *后面jsp引擎釋放它時就會報錯提示Stream closed;
                 *但是在websphere發布環境中不會,應該是容器在釋放對象前進行過判斷,這里體現了websphere容器的容錯性
                 *測試:在jsp中java代碼區直接寫一句:out.close();打開這個jsp,后台會直接報錯;
                 *所以,不要在jsp中調用out.close()手動關閉jsp這個out內置對象;
                 * 除非:
                 * out = pageContext.pushBody();
                 * out.close();
                 * 這樣不會報錯,是因為:
                 * 一開始out=pageContext.getOut()得到的是jsp內置out對象,后來pushBody得到的是一個新的ContextBody對象,他們是二個對象
                 * ContextBody是JspWriter的子類;即:jsp內置out對象是父,pushbody得到的是子,
                 * 所以這里的out.close()其實不是close掉jsp的內置out對象,而是ContextBody的實例對象;
                 * 總結:為了在tomcat和websphere中的通用:
                 * 不要寫out = pageContext.pushBody();也不要手動調用 out.close();
                 * */
            }
        }
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM