日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

深入分析JavaWeb Item7 -- HttpServletResponse详解

發(fā)布時(shí)間:2023/12/9 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入分析JavaWeb Item7 -- HttpServletResponse详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Web服務(wù)器收到客戶端的http請(qǐng)求,會(huì)針對(duì)每一次請(qǐng)求,分別創(chuàng)建一個(gè)用于代表請(qǐng)求的request對(duì)象、和代表響應(yīng)的response對(duì)象。request和response對(duì)象即然代表請(qǐng)求和響應(yīng),那我們要獲取客戶機(jī)提交過來的數(shù)據(jù),只需要找request對(duì)象就行了。要向客戶機(jī)輸出數(shù)據(jù),只需要找response對(duì)象就行了。

一、HttpServletResponse對(duì)象介紹

  

  HttpServletResponse對(duì)象代表服務(wù)器的響應(yīng)。這個(gè)對(duì)象中封裝了向客戶端發(fā)送數(shù)據(jù)、發(fā)送響應(yīng)頭,發(fā)送響應(yīng)狀態(tài)碼的方法。查看HttpServletResponse的API,可以看到這些相關(guān)的方法。

1.1、負(fù)責(zé)向客戶端(瀏覽器)發(fā)送數(shù)據(jù)的相關(guān)方法

  

1.2、負(fù)責(zé)向客戶端(瀏覽器)發(fā)送響應(yīng)頭的相關(guān)方法

  

  

1.3、負(fù)責(zé)向客戶端(瀏覽器)發(fā)送響應(yīng)狀態(tài)碼的相關(guān)方法

  

1.4、響應(yīng)狀態(tài)碼的常量

  HttpServletResponse定義了很多狀態(tài)碼的常量(具體可以查看Servlet的API),當(dāng)需要向客戶端發(fā)送響應(yīng)狀態(tài)碼時(shí),可以使用這些常量,避免了直接寫數(shù)字,常見的狀態(tài)碼對(duì)應(yīng)的常量:

  • 狀態(tài)碼404對(duì)應(yīng)的常量

  

  • 狀態(tài)碼200對(duì)應(yīng)的常量

  

  • 狀態(tài)碼500對(duì)應(yīng)的常量

  

二、HttpServletResponse對(duì)象常見應(yīng)用

2.1、使用OutputStream流向客戶端瀏覽器輸出中文數(shù)據(jù)

使用OutputStream流輸出中文注意問題:

  <font color="red">在服務(wù)器端,數(shù)據(jù)是以哪個(gè)碼表輸出的,那么就要控制客戶端瀏覽器以相應(yīng)的碼表打開,比如:outputStream.write("中國".getBytes("UTF-8"));使用OutputStream流向客戶端瀏覽器輸出中文,以UTF-8的編碼進(jìn)行輸出,此時(shí)就要控制客戶端瀏覽器以UTF-8的編碼打開,否則顯示的時(shí)候就會(huì)出現(xiàn)中文亂碼,那么在服務(wù)器端如何控制客戶端瀏覽器以以UTF-8的編碼顯示數(shù)據(jù)呢?可以通過設(shè)置響應(yīng)頭控制瀏覽器的行為,例如:response.setHeader("content-type", "text/html;charset=UTF-8");通過設(shè)置響應(yīng)頭控制瀏覽器以UTF-8的編碼顯示數(shù)據(jù)。</font>

范例:使用OutputStream流向客戶端瀏覽器輸出"中國"這兩個(gè)漢字

package gacl.response.study;import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ResponseDemo01 extends HttpServlet { private static final long serialVersionUID = 4312868947607181532L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { outputChineseByOutputStream(response);//使用OutputStream流輸出中文 } /** * 使用OutputStream流輸出中文 * @param request * @param response * @throws IOException */ public void outputChineseByOutputStream(HttpServletResponse response) throws IOException{ /**使用OutputStream輸出中文注意問題: * 在服務(wù)器端,數(shù)據(jù)是以哪個(gè)碼表輸出的,那么就要控制客戶端瀏覽器以相應(yīng)的碼表打開, * 比如:outputStream.write("中國".getBytes("UTF-8"));//使用OutputStream流向客戶端瀏覽器輸出中文,以UTF-8的編碼進(jìn)行輸出 * 此時(shí)就要控制客戶端瀏覽器以UTF-8的編碼打開,否則顯示的時(shí)候就會(huì)出現(xiàn)中文亂碼,那么在服務(wù)器端如何控制客戶端瀏覽器以以UTF-8的編碼顯示數(shù)據(jù)呢? * 可以通過設(shè)置響應(yīng)頭控制瀏覽器的行為,例如: * response.setHeader("content-type", "text/html;charset=UTF-8");//通過設(shè)置響應(yīng)頭控制瀏覽器以UTF-8的編碼顯示數(shù)據(jù) */ String data = "中國"; OutputStream outputStream = response.getOutputStream();//獲取OutputStream輸出流 response.setHeader("content-type", "text/html;charset=UTF-8");//通過設(shè)置響應(yīng)頭控制瀏覽器以UTF-8的編碼顯示數(shù)據(jù),如果不加這句話,那么瀏覽器顯示的將是亂碼 /** * data.getBytes()是一個(gè)將字符轉(zhuǎn)換成字節(jié)數(shù)組的過程,這個(gè)過程中一定會(huì)去查碼表, * 如果是中文的操作系統(tǒng)環(huán)境,默認(rèn)就是查找查GB2312的碼表, * 將字符轉(zhuǎn)換成字節(jié)數(shù)組的過程就是將中文字符轉(zhuǎn)換成GB2312的碼表上對(duì)應(yīng)的數(shù)字 * 比如: "中"在GB2312的碼表上對(duì)應(yīng)的數(shù)字是98 * "國"在GB2312的碼表上對(duì)應(yīng)的數(shù)字是99 */ /** * getBytes()方法如果不帶參數(shù),那么就會(huì)根據(jù)操作系統(tǒng)的語言環(huán)境來選擇轉(zhuǎn)換碼表,如果是中文操作系統(tǒng),那么就使用GB2312的碼表 */ byte[] dataByteArr = data.getBytes("UTF-8");//將字符轉(zhuǎn)換成字節(jié)數(shù)組,指定以UTF-8編碼進(jìn)行轉(zhuǎn)換 outputStream.write(dataByteArr);//使用OutputStream流向客戶端輸出字節(jié)數(shù)組 } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

運(yùn)行結(jié)果如下:

  

  客戶端瀏覽器接收到數(shù)據(jù)后,就按照響應(yīng)頭上設(shè)置的字符編碼來解析數(shù)據(jù),如下所示:

  

2.2、使用PrintWriter流向客戶端瀏覽器輸出中文數(shù)據(jù)

使用PrintWriter流輸出中文注意問題:

  <font color="red"> 在獲取PrintWriter輸出流之前首先使用"response.setCharacterEncoding(charset)"設(shè)置字符以什么樣的編碼輸出到瀏覽器,如:response.setCharacterEncoding("UTF-8");設(shè)置將字符以"UTF-8"編碼輸出到客戶端瀏覽器,然后再使用response.getWriter();獲取PrintWriter輸出流</font>. 這兩個(gè)步驟不能顛倒,如下:

response.setCharacterEncoding("UTF-8");//設(shè)置將字符以"UTF-8"編碼輸出到客戶端瀏覽器 /*** PrintWriter out = response.getWriter();這句代碼必須放在response.setCharacterEncoding("UTF-8");之后 * 否則response.setCharacterEncoding("UTF-8")這行代碼的設(shè)置將無效,瀏覽器顯示的時(shí)候還是亂碼 */ PrintWriter out = response.getWriter();//獲取PrintWriter輸出流

  然后再使用response.setHeader("content-type", "text/html;charset=字符編碼");設(shè)置響應(yīng)頭,控制瀏覽器以指定的字符編碼編碼進(jìn)行顯示,例如:

//通過設(shè)置響應(yīng)頭控制瀏覽器以UTF-8的編碼顯示數(shù)據(jù),如果不加這句話,那么瀏覽器顯示的將是亂碼response.setHeader("content-type", "text/html;charset=UTF-8");

上述兩步可以合成一步完成:

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

  除了可以使用response.setHeader("content-type", "text/html;charset=字符編碼");設(shè)置響應(yīng)頭來控制瀏覽器以指定的字符編碼編碼進(jìn)行顯示這種方式之外,還可以用如下的方式來模擬響應(yīng)頭的作用.

/*** 多學(xué)一招:使用HTML語言里面的<meta>標(biāo)簽來控制瀏覽器行為,模擬通過設(shè)置響應(yīng)頭控制瀏覽器行為*response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>"); * 等同于response.setHeader("content-type", "text/html;charset=UTF-8"); */ response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");

范例:使用PrintWriter流向客戶端瀏覽器輸出"中國"這兩個(gè)漢字

package gacl.response.study;import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ResponseDemo01 extends HttpServlet { private static final long serialVersionUID = 4312868947607181532L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { outputChineseByPrintWriter(response);//使用PrintWriter流輸出中文 } /** * 使用PrintWriter流輸出中文 * @param request * @param response * @throws IOException */ public void outputChineseByPrintWriter(HttpServletResponse response) throws IOException{ String data = "中國"; //通過設(shè)置響應(yīng)頭控制瀏覽器以UTF-8的編碼顯示數(shù)據(jù),如果不加這句話,那么瀏覽器顯示的將是亂碼 //response.setHeader("content-type", "text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8");//設(shè)置將字符以"UTF-8"編碼輸出到客戶端瀏覽器 /** * PrintWriter out = response.getWriter();這句代碼必須放在response.setCharacterEncoding("UTF-8");之后 * 否則response.setCharacterEncoding("UTF-8")這行代碼的設(shè)置將無效,瀏覽器顯示的時(shí)候還是亂碼 */ PrintWriter out = response.getWriter();//獲取PrintWriter輸出流 /** * 多學(xué)一招:使用HTML語言里面的<meta>標(biāo)簽來控制瀏覽器行為,模擬通過設(shè)置響應(yīng)頭控制瀏覽器行為 * out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>"); * 等同于response.setHeader("content-type", "text/html;charset=UTF-8"); */ out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>"); out.write(data);//使用PrintWriter流向客戶端輸出字符 } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

  當(dāng)需要向?yàn)g覽器輸出字符數(shù)據(jù)時(shí),使用PrintWriter比較方便,省去了將字符轉(zhuǎn)換成字節(jié)數(shù)組那一步。

2.3、使用OutputStream或者PrintWriter向客戶端瀏覽器輸出數(shù)字

比如有如下的代碼:

package gacl.response.study;import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ResponseDemo01 extends HttpServlet { private static final long serialVersionUID = 4312868947607181532L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { outputOneByOutputStream(response);//使用OutputStream輸出1到客戶端瀏覽器 } /** * 使用OutputStream流輸出數(shù)字1 * @param request * @param response * @throws IOException */ public void outputOneByOutputStream(HttpServletResponse response) throws IOException{ response.setHeader("content-type", "text/html;charset=UTF-8"); OutputStream outputStream = response.getOutputStream(); outputStream.write("使用OutputStream流輸出數(shù)字1:".getBytes("UTF-8")); outputStream.write(1); } }

  運(yùn)行上面代碼顯示的結(jié)果如下:

  

  運(yùn)行的結(jié)果和我們想象中的不一樣,數(shù)字1沒有輸出來,下面我們修改一下上面的outputOneByOutputStream方法的代碼,修改后的代碼如下:

/*** 使用OutputStream流輸出數(shù)字1* @param request* @param response* @throws IOException */public void outputOneByOutputStream(HttpServletResponse response) throws IOException{ response.setHeader("content-type", "text/html;charset=UTF-8"); OutputStream outputStream = response.getOutputStream(); outputStream.write("使用OutputStream流輸出數(shù)字1:".getBytes("UTF-8")); //outputStream.write(1); outputStream.write((1+"").getBytes()); }

  1+""這一步是將數(shù)字1和一個(gè)空字符串相加,這樣處理之后,數(shù)字1就變成了字符串1了,然后再將字符串1轉(zhuǎn)換成字節(jié)數(shù)組使用OutputStream進(jìn)行輸出,此時(shí)看到的結(jié)果如下:

  

  這次可以看到輸出來的1了,這說明了一個(gè)問題:在開發(fā)過程中,如果希望服務(wù)器輸出什么瀏覽器就能看到什么,那么在服務(wù)器端都要以字符串的形式進(jìn)行輸出。

  如果使用PrintWriter流輸出數(shù)字,那么也要先將數(shù)字轉(zhuǎn)換成字符串后再輸出,如下:

/*** 使用PrintWriter流輸出數(shù)字1* @param request* @param response* @throws IOException */public void outputOneByPrintWriter(HttpServletResponse response) throws IOException{ response.setHeader("content-type", "text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter();//獲取PrintWriter輸出流 out.write("使用PrintWriter流輸出數(shù)字1:"); out.write(1+""); }

2.4、文件下載

  文件下載功能是web開發(fā)中經(jīng)常使用到的功能,使用HttpServletResponse對(duì)象就可以實(shí)現(xiàn)文件的下載

文件下載功能的實(shí)現(xiàn)思路:

  1.獲取要下載的文件的絕對(duì)路徑

  2.獲取要下載的文件名

  3.設(shè)置content-disposition響應(yīng)頭控制瀏覽器以下載的形式打開文件

  4.獲取要下載的文件輸入流

  5.創(chuàng)建數(shù)據(jù)緩沖區(qū)

  6.通過response對(duì)象獲取OutputStream流

  7.將FileInputStream流寫入到buffer緩沖區(qū)

  8.使用OutputStream將緩沖區(qū)的數(shù)據(jù)輸出到客戶端瀏覽器

范例:使用Response實(shí)現(xiàn)文件下載

package gacl.response.study; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author gacl * 文件下載 */ public class ResponseDemo02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { downloadFileByOutputStream(response);//下載文件,通過OutputStream流 } /** * 下載文件,通過OutputStream流 * @param response * @throws FileNotFoundException * @throws IOException */ private void downloadFileByOutputStream(HttpServletResponse response) throws FileNotFoundException, IOException { //1.獲取要下載的文件的絕對(duì)路徑 String realPath = this.getServletContext().getRealPath("/download/1.JPG"); //2.獲取要下載的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1); //3.設(shè)置content-disposition響應(yīng)頭控制瀏覽器以下載的形式打開文件 response.setHeader("content-disposition", "attachment;filename="+fileName); //4.獲取要下載的文件輸入流 InputStream in = new FileInputStream(realPath); int len = 0; //5.創(chuàng)建數(shù)據(jù)緩沖區(qū) byte[] buffer = new byte[1024]; //6.通過response對(duì)象獲取OutputStream流 OutputStream out = response.getOutputStream(); //7.將FileInputStream流寫入到buffer緩沖區(qū) while ((len = in.read(buffer)) > 0) { //8.使用OutputStream將緩沖區(qū)的數(shù)據(jù)輸出到客戶端瀏覽器 out.write(buffer,0,len); } in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

運(yùn)行結(jié)果如下所示:

  

范例:使用Response實(shí)現(xiàn)中文文件下載

  下載中文文件時(shí),需要注意的地方就是中文文件名要使用URLEncoder.encode方法進(jìn)行編碼(URLEncoder.encode(fileName, "字符編碼")),否則會(huì)出現(xiàn)文件名亂碼。

package gacl.response.study; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author gacl * 文件下載 */ public class ResponseDemo02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { downloadChineseFileByOutputStream(response);//下載中文文件 } /** * 下載中文文件,中文文件下載時(shí),文件名要經(jīng)過URL編碼,否則會(huì)出現(xiàn)文件名亂碼 * @param response * @throws FileNotFoundException * @throws IOException */ private void downloadChineseFileByOutputStream(HttpServletResponse response) throws FileNotFoundException, IOException { String realPath = this.getServletContext().getRealPath("/download/張家界國家森林公園.JPG");//獲取要下載的文件的絕對(duì)路徑 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//獲取要下載的文件名 //設(shè)置content-disposition響應(yīng)頭控制瀏覽器以下載的形式打開文件,中文文件名要使用URLEncoder.encode方法進(jìn)行編碼,否則會(huì)出現(xiàn)文件名亂碼 response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8")); InputStream in = new FileInputStream(realPath);//獲取文件輸入流 int len = 0; byte[] buffer = new byte[1024]; OutputStream out = response.getOutputStream(); while ((len = in.read(buffer)) > 0) { out.write(buffer,0,len);//將緩沖區(qū)的數(shù)據(jù)輸出到客戶端瀏覽器 } in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

運(yùn)行結(jié)果如下所示:

  

  文件下載注意事項(xiàng):編寫文件下載功能時(shí)推薦使用OutputStream流,避免使用PrintWriter流,因?yàn)镺utputStream流是字節(jié)流,可以處理任意類型的數(shù)據(jù),而PrintWriter流是字符流,只能處理字符數(shù)據(jù),如果用字符流處理字節(jié)數(shù)據(jù),會(huì)導(dǎo)致數(shù)據(jù)丟失。

范例:使用PrintWriter流下載文件

package gacl.response.study; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author gacl * 文件下載 */ public class ResponseDemo02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { downloadFileByPrintWriter(response);//下載文件,通過PrintWriter流 } /** * 下載文件,通過PrintWriter流,雖然也能夠?qū)崿F(xiàn)下載,但是會(huì)導(dǎo)致數(shù)據(jù)丟失,因此不推薦使用PrintWriter流下載文件 * @param response * @throws FileNotFoundException * @throws IOException */ private void downloadFileByPrintWriter(HttpServletResponse response) throws FileNotFoundException, IOException { String realPath = this.getServletContext().getRealPath("/download/張家界國家森林公園.JPG");//獲取要下載的文件的絕對(duì)路徑 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//獲取要下載的文件名 //設(shè)置content-disposition響應(yīng)頭控制瀏覽器以下載的形式打開文件,中文文件名要使用URLEncoder.encode方法進(jìn)行編碼 response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8")); FileReader in = new FileReader(realPath); int len = 0; char[] buffer = new char[1024]; PrintWriter out = response.getWriter(); while ((len = in.read(buffer)) > 0) { out.write(buffer,0,len);//將緩沖區(qū)的數(shù)據(jù)輸出到客戶端瀏覽器 } in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

運(yùn)行結(jié)果如下:

  

正常彈出下載框,此時(shí)我們點(diǎn)擊【保存】按鈕將文件下載下來,如下所示:

  

  可以看到,只下載了5.25MB,而這張圖片的原始大小卻是

  

  這說明在下載的時(shí)候數(shù)據(jù)丟失了,所以下載不完全,所以這張圖片雖然能夠正常下載下來,但是卻是無法打開的,因?yàn)閬G失掉了部分?jǐn)?shù)據(jù),如下所示:

  

  所以使用PrintWriter流處理字節(jié)數(shù)據(jù),會(huì)導(dǎo)致數(shù)據(jù)丟失,這一點(diǎn)千萬要注意,因此在編寫下載文件功能時(shí),要使用OutputStream流,避免使用PrintWriter流,因?yàn)镺utputStream流是字節(jié)流,可以處理任意類型的數(shù)據(jù),而PrintWriter流是字符流,只能處理字符數(shù)據(jù),如果用字符流處理字節(jié)數(shù)據(jù),會(huì)導(dǎo)致數(shù)據(jù)丟失。

?

from:?https://segmentfault.com/a/1190000004113284

總結(jié)

以上是生活随笔為你收集整理的深入分析JavaWeb Item7 -- HttpServletResponse详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。