Java Web請(qǐng)求與響應(yīng)實(shí)例詳解
Servlet最主要作用就是處理客戶端請(qǐng)求并作出回應(yīng),為此,針對(duì)每次請(qǐng)求,Web容器在調(diào)用service()之前都會(huì)創(chuàng)建兩個(gè)對(duì)象,分別是HttpServletRequest和HttpServletResponse。其中HttpServletRequest封裝HTTP請(qǐng)求消息,HttpServletResponse封裝HTTP響應(yīng)消息。需要注意的是,Web服務(wù)器運(yùn)行過(guò)程中,每個(gè)Servlet都會(huì)只創(chuàng)建一個(gè)實(shí)例對(duì)象,不過(guò)每次請(qǐng)求都會(huì)調(diào)用Servlet實(shí)例的service(ServletRequest req, ServletResponse res)方法,這里HttpServletRequest是ServletRequest的子類(lèi),HttpServletResponse是ServletResponse的子類(lèi)。
HttpServletRequest和HttpServletResponse接口繼承關(guān)系圖如下所示:
1、HttpServletResponse
HttpServletResponse接口繼承自ServletResponse接口,由于HTTP響應(yīng)消息分為狀態(tài)行、響應(yīng)消息體、消息體三部分,因此,在HttpServletResponse接口中定義了向客戶端發(fā)送響應(yīng)狀態(tài)碼、響應(yīng)消息頭、響應(yīng)消息體的方法。雖然HttpServletResponse接口中的方法較多,但是我們常用的也就是那么幾個(gè),如果用到其他的方法了可以閱讀響應(yīng)的源碼或者相關(guān)資料就行了。
發(fā)送狀態(tài)碼相關(guān)函數(shù)
方法
說(shuō)明
public void setStatus(int sc)
設(shè)置響應(yīng)消息狀態(tài)碼,Web服務(wù)器默認(rèn)產(chǎn)生一個(gè)狀態(tài)碼為200的狀態(tài)行
public void sendError(int sc)
發(fā)送表示錯(cuò)誤信息的狀態(tài)碼,第二個(gè)方法還增加了一個(gè)用于提示說(shuō)明的文本信息
public void sendError(int sc, String msg)
發(fā)送響應(yīng)消息頭相關(guān)函數(shù)
方法
說(shuō)明
public void addHeader(String name, String value)
設(shè)置HTTP響應(yīng)頭字段,name指定字段名稱(chēng),value指定字段值。addHeader可以增加同名的響應(yīng)頭字段,setHeader則會(huì)覆蓋同名的頭字段
public void setHeader(String name, String value)
public void setContentLength(int len)
設(shè)置響應(yīng)消息的實(shí)體內(nèi)容的大小,單位為字節(jié),即設(shè)置Content-Length字段的值
public void setContentType(String type)
設(shè)置Servlet輸出內(nèi)容的MIME類(lèi)型,即設(shè)置Content-Type字段的值
public void setCharacterEncoding(String charset)
設(shè)置輸出內(nèi)容字符編碼,即設(shè)置Content-Type字段的值,注意,該方法優(yōu)先級(jí)比setContentType的高
public void sendRedirect(String location)
Servlet請(qǐng)求重定向
發(fā)送響應(yīng)消息體相關(guān)函數(shù)
方法 | 說(shuō)明 |
public ServletOutputStream getOutputStream() | 獲取HttpServletResponse的字節(jié)輸出流ServletOutputStram類(lèi)型 |
public PrintWriter getWriter() | 獲取HttpServletResponse的字符輸出流ServletWriter類(lèi)型 |
中文輸出亂碼問(wèn)題
計(jì)算機(jī)中的數(shù)據(jù)都是以二進(jìn)制形式存儲(chǔ)的,因此,傳輸文本時(shí),就會(huì)發(fā)生字符的字節(jié)之間的轉(zhuǎn)換。字符與字節(jié)之間的轉(zhuǎn)換時(shí)通過(guò)查碼表完成的,字符轉(zhuǎn)換為字節(jié)的過(guò)程稱(chēng)為編碼,字節(jié)轉(zhuǎn)換為字符的過(guò)程稱(chēng)為解碼,如果編碼和解碼使用的碼表不一樣,則會(huì)出現(xiàn)亂碼問(wèn)題。
注意:HttpServletResponse對(duì)象的字符輸出流在編碼時(shí),默認(rèn)采用的是ISO 8859-1編碼,該編碼方式不兼容中文,比如會(huì)將"中國(guó)"編碼為"63 63"(在ISO 8959-1的碼表中查不到的字符會(huì)顯示63)。當(dāng)瀏覽器對(duì)接收到的數(shù)據(jù)進(jìn)行解碼時(shí),會(huì)默認(rèn)采用GB2312,將"63"解碼為"?",瀏覽器就將"中國(guó)"兩個(gè)字符解碼為"??"。
HttpServletResponse程序示例
package zzz; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Hello extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // 設(shè)置響應(yīng)消息編碼,注釋后"中國(guó)"會(huì)顯示"??"亂碼 response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("hello 中國(guó)"); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { this.doGet(request, response); } }
有時(shí)會(huì)遇到定時(shí)跳轉(zhuǎn)頁(yè)面的問(wèn)題,HTTP中Refresh頭字段可以通知瀏覽器在指定的時(shí)間內(nèi)自動(dòng)刷新并跳轉(zhuǎn)到其他頁(yè)面,網(wǎng)頁(yè)定時(shí)刷新并跳轉(zhuǎn)到指定頁(yè)面。
package zzz; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Hello extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // 設(shè)置響應(yīng)消息編碼 response.setContentType("text/html;charset=utf-8"); response.setHeader("Refresh", "2;url=http://www.baidu.com"); PrintWriter out = response.getWriter(); out.println("hello 中國(guó),2秒后跳轉(zhuǎn)到百度..."); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { this.doGet(request, response); } }
2、HttpServletRequest
HttpServletRequest接口繼承ServletRequest接口,專(zhuān)門(mén)用于封狀HTTP請(qǐng)求消息。由于HTTP請(qǐng)求信息包括請(qǐng)求行、請(qǐng)求頭和請(qǐng)求體三部分,所以HttpServletRequest接口定義了獲取請(qǐng)求行、請(qǐng)求頭和請(qǐng)求體的相關(guān)方法。
獲取請(qǐng)求行的相關(guān)方法
方法 | 說(shuō)明 |
public String getMethod() | 獲取HTTP請(qǐng)求方式,POST、GET等 |
public String getRequestURI() | 獲取請(qǐng)求行中資源名稱(chēng)部分 |
public String getQueryString() | 獲取請(qǐng)求行中的參數(shù)部分 |
public String getProtocol() | 獲取請(qǐng)求行中協(xié)議名稱(chēng)和版本,如HTTP 1.1 |
public String getContextPath() | 獲取請(qǐng)求URL中屬于Web應(yīng)用程序的路徑 |
其實(shí)關(guān)于請(qǐng)求行的方法從方法名中就可以看出其作用,這里就不一一貼出來(lái)了。
獲取請(qǐng)求消息頭的相關(guān)方法
方法 | 說(shuō)明 |
public String getHeader(String name) | 獲取指定字段的值,如果沒(méi)有返回null,如果有多個(gè)返回第一個(gè)值 |
public Enumeration<String> getHeaders(String name) | 返回一個(gè)指定字段的Enumeration集合對(duì)象 |
public Enumeration<String> getHeaderNames() | 返回一個(gè)包含所有字段的Enumeration集合對(duì)象 |
public String getContentType() | 獲取Content-Type字段的值 |
打印請(qǐng)求消息頭字段的所有值
package zzz; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Hello extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // 設(shè)置響應(yīng)消息編碼 response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); Enumeration<String> names = request.getHeaderNames(); while (names.hasMoreElements()) { String name = names.nextElement(); String value = request.getHeader(name); out.println(name + ": " + value + "</br>"); } } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { this.doGet(request, response); } }
獲取請(qǐng)求體的相關(guān)方法
方法
說(shuō)明
public ServletInputStream getInputStream()
獲取請(qǐng)求的ServletInputStream對(duì)象,如果實(shí)體內(nèi)容為非文本,只能通過(guò)getInputStream方法獲取請(qǐng)求體消息體
public BufferedReader getReader()
獲取請(qǐng)求的BufferedReader對(duì)象,該對(duì)象會(huì)將實(shí)體內(nèi)容字節(jié)數(shù)據(jù)轉(zhuǎn)換為指定字符集編碼的文本字符串
獲取請(qǐng)求參數(shù)
方法 | 說(shuō)明 |
public String getParameter(String name) | 獲取指定的參數(shù)值,沒(méi)有該參數(shù)返回null |
public Enumeration<String> getParameterNames() | 返回一個(gè)包含所有參數(shù)名的Enumeration對(duì)象 |
public String[] getParameterValues(String name) | HTTP請(qǐng)求中可能有多個(gè)相同的參數(shù),獲取同一個(gè)參數(shù)名對(duì)應(yīng)的所有參數(shù)值 |
3、RequestDispatcher接口
當(dāng)一個(gè)Web資源受到客戶端請(qǐng)求后,如果希望服務(wù)器通知另外一個(gè)資源如處理請(qǐng)求,除了使用功能sendRedirect()實(shí)現(xiàn)重定向外,還可以通過(guò)RequestDispatcher接口的實(shí)例對(duì)象來(lái)實(shí)現(xiàn),在ServletRequest接口中定義了一個(gè)獲取RequestDispatcher對(duì)象的方法--getRequestDispatcher(String path),它返回某個(gè)路徑所指定資源的RequestDispatcher對(duì)象,參數(shù)path必須以"/"開(kāi)頭,用于表示當(dāng)前Web應(yīng)用的根目錄,也就是path路徑必須是在本W(wǎng)eb程序中,否則會(huì)出現(xiàn)異常。
RequestDispatcher接口中方法
方法 | 功能 |
public void forward(ServletRequest request, ServletResponse response) | 將一個(gè)Servlet傳遞給另外一個(gè)Web資源,將請(qǐng)求傳遞給其他資源進(jìn)行響應(yīng) |
public void include(ServletRequest request, ServletResponse response) | 用于將其他資源作為當(dāng)前響應(yīng)內(nèi)容包含進(jìn)來(lái) |
以上所述是小編給大家介紹的Java Web請(qǐng)求與響應(yīng)實(shí)例詳解的相關(guān)內(nèi)容,希望對(duì)大家有所幫助!
- Android中通過(guò)RxJava進(jìn)行響應(yīng)式程序設(shè)計(jì)的入門(mén)指南
- JavaFX桌面應(yīng)用未響應(yīng)問(wèn)題解決方案
- Java response響應(yīng)體和文件下載實(shí)現(xiàn)原理
- java實(shí)現(xiàn)響應(yīng)重定向發(fā)送post請(qǐng)求操作示例
- JavaWeb Refresh響應(yīng)頭代碼實(shí)例詳解
- javaweb如何實(shí)現(xiàn)請(qǐng)求和響應(yīng)
- java web請(qǐng)求和響應(yīng)中出現(xiàn)中文亂碼問(wèn)題的解析
- Java并發(fā)編程之性能、擴(kuò)展性和響應(yīng)
- 淺談Java響應(yīng)式系統(tǒng)
相關(guān)文章
解析spring-security權(quán)限控制和校驗(yàn)的問(wèn)題
這篇文章主要介紹了解析spring-security權(quán)限控制和校驗(yàn)的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03基于Java實(shí)現(xiàn)多線程下載并允許斷點(diǎn)續(xù)傳
這篇文章主要介紹了基于Java實(shí)現(xiàn)多線程下載并允許斷點(diǎn)續(xù)傳,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Java內(nèi)存釋放實(shí)現(xiàn)代碼案例
這篇文章主要介紹了Java內(nèi)存釋放實(shí)現(xiàn)代碼案例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12詳解Spring Boot中整合Sharding-JDBC讀寫(xiě)分離示例
這篇文章主要介紹了詳解Spring Boot中整合Sharding-JDBC讀寫(xiě)分離示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03解決mybatis 數(shù)據(jù)庫(kù)date 與 java中Date類(lèi)型映射問(wèn)題
這篇文章主要介紹了解決mybatis 數(shù)據(jù)庫(kù)date 與 java中Date類(lèi)型映射問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)吧2020-11-11Idea 2020.2安裝MyBatis Log Plugin 不可用的解決方法
小編在使用時(shí)發(fā)現(xiàn)Idea 2020.2 MyBatis Log Plugin 收費(fèi)了,這個(gè)可以替代用,小編特此把解決方案分享到腳本之家平臺(tái)供大家參考,感興趣的朋友一起看看吧2020-11-11IntelliJ IDEA中出現(xiàn)"PSI and index do not match"錯(cuò)誤的解決辦法
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA中出現(xiàn)"PSI and index do not match"錯(cuò)誤的解決辦法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10簡(jiǎn)單了解synchronized和lock的區(qū)別
這篇文章主要介紹了簡(jiǎn)單了解synchronized和lock的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09