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)響應體設定文字
獲得字元流,通過字元流的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細節點:
- response獲得的流不需要手動關閉,web容器(tomcat容器)會幫助我們關閉,
- getWriter和getOutputStream不能同時呼叫
- 重定向語句一般作為終結程式碼