一、HttpServletResponse概述
創(chuàng)建Servlet時(shí)會(huì)覆蓋service()方法,或doGet()/doPost()
這些方法都有兩個(gè)參數(shù),一個(gè)為代表請(qǐng)求的request和代表響應(yīng)response。
- service方法中的response的類(lèi)型是ServletResponse
- doGet/doPost方法的response的類(lèi)型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加強(qiáng)大,本文使用的是HttpServletResponse。
二、response的運(yùn)行流程
三、通過(guò)抓包工具抓取Http響應(yīng)
因?yàn)閞esponse代表響應(yīng),所以我們可以通過(guò)該對(duì)象分別設(shè)置Http響應(yīng)的響應(yīng)行,響應(yīng)頭和響應(yīng)體
四、通過(guò)response設(shè)置響應(yīng)行的狀態(tài)碼
setStatus(int sc)
(一般不用自己設(shè)置狀態(tài)碼)
五、通過(guò)response設(shè)置響應(yīng)頭
addHeader(String name, String value)
addIntHeader(String name, int value)
addDateHeader(String name, long date)
//這個(gè)方法最重要
setHeader(String name, String value)
setDateHeader(String name, long date)
setIntHeader(String name, int value)
其中,add表示添加,而set表示設(shè)置
-
重定向
概念:相當(dāng)于找第一個(gè)人借錢(qián)時(shí)他說(shuō)沒(méi)錢(qián),然后讓你去找第二個(gè)人
實(shí)例代碼:狀態(tài)碼設(shè)置為302,響應(yīng)頭中的location代表重定向的地址
實(shí)例:訪問(wèn)RefreshServlet后5秒后就會(huì)跳轉(zhuǎn)到百度的頁(yè)面
六、通過(guò)response設(shè)置響應(yīng)體
(1)響應(yīng)體設(shè)置文本
PrintWriter getWriter()
獲得字符流,通過(guò)字符流的write(String s)方法可以將字符串設(shè)置到response 緩沖區(qū)中,隨后Tomcat會(huì)將response緩沖區(qū)中的內(nèi)容組裝成Http響應(yīng)返回給瀏覽 器端。
-
關(guān)于設(shè)置中文的亂碼問(wèn)題
原因:response緩沖區(qū)的默認(rèn)編碼是iso8859-1,此碼表中沒(méi)有中文,可以通過(guò) response的setCharacterEncoding(String charset) 設(shè)置response的編碼
但我們發(fā)現(xiàn)客戶端還是不能正常顯示文字
原因:我們將response緩沖區(qū)的編碼設(shè)置成UTF-8,但瀏覽器的默認(rèn)編碼是本地系 統(tǒng)的編碼,因?yàn)槲覀兌际侵形南到y(tǒng),所以客戶端瀏覽器的默認(rèn)編碼是GBK,我們可以 手動(dòng)修改瀏覽器的編碼是UTF-8(但面向客戶的話此方法很麻煩)。
我們還可以在代碼中指定瀏覽器解析頁(yè)面的編碼方式,
通過(guò)response的setContentType(String type)方法指定頁(yè)面解析時(shí)的編碼是UTF-8
response.setContentType("text/html;charset=UTF-8");
上面的代碼不僅可以指定瀏覽器解析頁(yè)面時(shí)的編碼,同時(shí)也內(nèi)含 setCharacterEncoding的功能
所以在實(shí)際開(kāi)發(fā)中只要編寫(xiě)
response.setContentType("text/html;charset=UTF-8");
就可以解決頁(yè)面輸出中文亂碼問(wèn)題。
(2)響應(yīng)頭設(shè)置字節(jié)
ServletOutputStream getOutputStream()
獲得字節(jié)流,通過(guò)該字節(jié)流的write(byte[] bytes)可以向response緩沖區(qū)中寫(xiě)入字 節(jié),在由Tomcat服務(wù)器將字節(jié)內(nèi)容組成Http響應(yīng)返回給瀏覽器。
實(shí)例:用字節(jié)流傳輸一張圖片,瀏覽器頁(yè)面獲得輸出的圖片信息會(huì)自動(dòng)解析渲染
注意上面用到的inputStream和outputStream的方法
inputstream的read (byte[] b) :
//從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)數(shù)組 b 中。以整數(shù)形式返回實(shí)際讀取的字節(jié)數(shù)。
void write(byte[] b, int off, int len)
//將指定 byte 數(shù)組中從偏移量 off 開(kāi)始的 len 個(gè)字節(jié)寫(xiě)入此輸出流。
七、案例-完成文件下載
文件下載的實(shí)質(zhì)就是文件拷貝,將文件從服務(wù)器端拷貝到瀏覽器端。所以文件下載需要IO技術(shù)將服務(wù)器端的文件使用InputStream讀取到,再使用 ServletOutputStream寫(xiě)到response緩沖區(qū)中
因?yàn)闉g覽器直接解析例如圖片等能夠解析的內(nèi)容顯示在頁(yè)面上,默認(rèn)不是提供下載,所以我們需要設(shè)置兩個(gè)響應(yīng)頭,告知瀏覽器文件的類(lèi)型和文件的打開(kāi)方式。
1)告知瀏覽器文件的類(lèi)型:
response.setContentType(文件的MIME類(lèi)型);
2)告示瀏覽器文件的打開(kāi)方式是下載:
response.setHeader("Content-Disposition","attachment;filename=文件名稱(chēng)");
可以將圖片從服務(wù)器端傳輸?shù)綖g覽器,但-
完整代碼如下:
Paste_Image.png 如果文件名為中文的情況下需要添加如下代碼
//獲得要下載的文件的名稱(chēng)
String filename = request.getParameter("filename");//????.jpg
//解決獲得中文參數(shù)的亂碼
filename = new String(filename.getBytes("ISO8859-1"),"UTF-8");//中文名.jpg
//獲得請(qǐng)求頭中的User-Agent
String agent = request.getHeader("User-Agent");
//根據(jù)不同瀏覽器進(jìn)行不同的編碼
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");
}
八、案例——驗(yàn)證碼
-
概念
1.驗(yàn)證碼是一張圖片,是在后臺(tái)通過(guò)java代碼動(dòng)態(tài)生成的,可以直接使用模版代碼
2.驗(yàn)證碼上的數(shù)字是隨機(jī)產(chǎn)生的
3.生成圖片后能在頁(yè)面顯示是通過(guò)outputstream的write方法把圖片內(nèi)容寫(xiě)入到response緩沖區(qū)
4.在html文件中的驗(yàn)證碼圖片標(biāo)簽中添加自動(dòng)生成圖片的Servlet頁(yè)面路徑,并添加單擊事件實(shí)現(xiàn)點(diǎn)擊更換驗(yàn)證碼圖片
九、response注意點(diǎn)
- response獲得的流不需要手動(dòng)關(guān)閉,Tomcat容器會(huì)幫助我們關(guān)閉
- getWriter和getOutoutStream不能同時(shí)調(diào)用