1. 程式人生 > 實用技巧 >HttpServletResponse(set方法)

HttpServletResponse(set方法)

我們在建立Servlet時會覆蓋service()方法,或doGet()/doPost(),這些方法都有兩個引數,一個為代表請求的request和代表響應response。

service方法中的response的型別是ServletResponse,而doGet/doPost方法的response的型別是HttpServletResponse,HttpServletResponse是ServletResponse的子介面,功能和方法更加強大。

1.response的執行流程

因為response代表響應,所以我們可以通過該物件分別設定Http響應的響應行,響 應頭和響應體

1.通過response設定響應行

設定響應行的狀態碼

setStatus(int sc)

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //相應行
        response.setStatus(404);
    }

2.通過response設定響應頭

addHeader(Stringname,Stringvalue)

addIntHeader(Stringname, int value)

addDateHeader(Stringname, long date)

setHeader(Stringname,Stringvalue)//給頭設定值

setDateHeader(Stringname, long date)

setIntHeader(Stringname, int value)

其中,add表示新增,而set表示設定

重定向需要:1.狀態碼:302

2.響應頭:location 代表重定向地址

MyServlet01直接跳轉到MyServlet02

public class MyServlet01 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //response.setStatus(302);//設定狀態碼302
        //設定Location頭
        //response.setHeader("Location","/Web03/MyServlet02" );
        //重定向
        response.sendRedirect("/Web03/MyServlet02");
    }

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

public class MyServlet02 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("hello dandan...");
    }

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

3.通過response設定響應體

設定定時重新整理

public class RefreshServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //定時shuaxin 
        response.setHeader("Refresh","5;url=http://www.baidu.com");
    }

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

(1)響應體設定文字

PrintWritergetWriter()

獲得字元流,通過字元流的write(Strings)方法可以將字串設定到response 緩衝區中,隨後Tomcat會將response緩衝區中的內容組裝成Http響應返回給瀏覽 器端。

關於設定中文的亂碼問題

原因:response緩衝區的預設編碼是iso8859-1,此碼錶中沒有中文,可以通過 response的setCharacterEncoding(Stringcharset)設定response的編碼

但我們發現客戶端還是不能正常顯示文字

原因:我們將response緩衝區的編碼設定成UTF-8,但瀏覽器的預設編碼是本地系 統的編碼,因為我們都是中文系統,所以客戶端瀏覽器的預設編碼是GBK,我們可以 手動修改瀏覽器的編碼是UTF-8。

我們還可以在程式碼中指定瀏覽器解析頁面的編碼方式,

通過response的setContentType(Stringtype)方法指定頁面解析時的編碼是UTF-8

response.setContentType("text/html;charset=UTF-8");

public class BodyServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //設定緩衝區的碼錶
        //response.setCharacterEncoding("utf-8");
        //設定瀏覽器解析碼錶
        response.setContentType("text/html;charset=utf-8");
        
        response.getWriter().write("你好");
    }

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

上面的程式碼不僅可以指定瀏覽器解析頁面時的編碼,同時也內含 setCharacterEncoding的功能,所以在實際開發中只要編寫response.setContentType("text/html;charset=UTF-8");就可以解決頁面輸出中文亂碼問題。

(2)響應頭設定位元組

ServletOutputStreamgetOutputStream()

獲得位元組流,通過該位元組流的write(byte[] bytes)可以向response緩衝區中寫入字 節,在由Tomcat伺服器將位元組內容組成Http響應返回給瀏覽器。

1.案例-完成檔案下載

檔案下載的實質就是檔案拷貝,將檔案從伺服器端拷貝到瀏覽器端。所以檔案下載需 要IO技術將伺服器端的檔案使用InputStream讀取到,在使用 ServletOutputStream寫到response緩衝區中

上述程式碼可以將圖片從伺服器端傳輸到瀏覽器,但瀏覽器直接解析圖片顯示在頁面上, 而不是提供下載,我們需要設定兩個響應頭,告知瀏覽器檔案的型別和檔案的開啟方 式。

1)告知瀏覽器檔案的型別:response.setContentType(檔案的MIME型別);

2)告示瀏覽器檔案的開啟方式是下載:

response.setHeader("Content-Disposition","attachment;filename=檔名稱");

但是,如果下載中文檔案,頁面在下載時會出現中文亂碼或不能顯示檔名的情況, 原因是不同的瀏覽器預設對下載檔案的編碼方式不同,ie是UTF-8編碼方式,而火狐 瀏覽器是Base64編碼方式。所裡這裡需要解決瀏覽器相容性問題,解決瀏覽器相容 性問題的首要任務是要辨別訪問者是ie還是火狐(其他),通過Http請求體中的一 個屬性可以辨別


解決亂碼方法如下(不要記憶--瞭解):

String filenameEncoder=””;

if (agent.contains("MSIE")) {

// IE瀏覽器

filenameEncoder= URLEncoder.encode(filename, "utf-8");

filenameEncoder= filenameEncoder.replace("+", " ");

} else if (agent.contains("Firefox")) {

// 火狐瀏覽器

BASE64Encoder base64Encoder = new BASE64Encoder();

filenameEncoder= "=?utf-8?B?"

+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";

} else {

// 其它瀏覽器

filenameEncoder= URLEncoder.encode(filename, "utf-8");

}

其中agent就是請求頭User-Agent的值

public class DownloadServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取檔名
        String filename=request.getParameter("filename");
        
        //解決中文亂碼
        filename=new String(filename.getBytes("ISO-8859-1"),"UTF-8");
        //獲取User-Agent頭,明確客戶端是什麼瀏覽器
                String agent=request.getHeader("User-Agent");
                
                String filenameEncoder="";
                if (agent.contains("MSIE")) {
                        // IE瀏覽器
                        filenameEncoder= URLEncoder.encode(filename, "utf-8");
                        filenameEncoder= filenameEncoder.replace("+", " ");
                } else if (agent.contains("Firefox")) {
                        // 火狐瀏覽器
                BASE64Encoder base64Encoder = new BASE64Encoder();
                        filenameEncoder= "=?utf-8?B?"
                                + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
                } else {
                        // 其它瀏覽器
                        filenameEncoder= URLEncoder.encode(filename, "utf-8");                
                }
                
                
                
        //圖片,txt下載
        //1.告知瀏覽器檔案MIME型別
        response.setContentType(getServletContext().getMimeType(filename));
        
        //2.告知瀏覽器改檔案的開啟方式是以附件方式開啟
        response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoder);
        //獲取檔案絕對
        String path=getServletContext().getRealPath("download/"+filename);
        //明確資料來源
        FileInputStream fis=new FileInputStream(path);
        //目的地
        ServletOutputStream out=response.getOutputStream();
        int len=0;
        byte[] bytes=new byte[1024];
        while((len=fis.read(bytes))!=-1){
            out.write(bytes,0,len);
        }
        fis.close();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
<body>
<a href="/Web03/DownloadServlet?filename=小薯條.jpg">小薯條.jpg</a>
<a href="/Web03/DownloadServlet?filename=a.wmv">a.wmv</a>
<a href="/Web03/DownloadServlet?filename=a.zip">a.zip</a>
<a href="/Web03/DownloadServlet?filename=a.txt">a.txt</a>
</body>

response細節點:

  1. response獲得的流不需要手動關閉,web容器(tomcat容器)會幫助我們關閉,
  2. getWriter和getOutputStream不能同時呼叫
  3. 重定向語句一般作為終結程式碼