護膚品網(wǎng)站建設分析網(wǎng)頁制作工具有哪些
?作者介紹:大二本科網(wǎng)絡工程專業(yè)在讀,持續(xù)學習Java,輸出優(yōu)質(zhì)文章
?所屬專欄:Java Web
?如果覺得文章寫的不錯,歡迎點個關注😉有寫的不好的地方也歡迎指正,一同進步😁
目錄
Request對象
1、Request繼承體系
2、Request獲取請求數(shù)據(jù)
2.1、獲取請求行數(shù)據(jù)
2.2、獲取請求頭數(shù)據(jù)
2.3、獲取請求體數(shù)據(jù)
2.4、獲取請求參數(shù)的通用方式
2.5、完整代碼
3、IDEA快速創(chuàng)建Servlet
4、請求參數(shù)中文亂碼問題
4.1、🔺POST請求解決方案
4.2、🔺🔺GET請求解決方案
5、Request請求轉(zhuǎn)發(fā)
Request對象
1、Request繼承體系
在學習這節(jié)內(nèi)容之前,先思考一個問題,前面在介紹Request和Reponse對象的時候:
- 當Servlet類實現(xiàn)的是Servlet接口的時候,service方法中的參數(shù)是ServletRequest和ServletResponse
- 當Servlet類繼承的是HttpServlet類的時候,doGet和doPost方法中的參數(shù)就變成HttpServletRequest和HttpServletReponse
那么:
- ServletRequest和HttpServletRequest的關系是什么?
- request對象是有誰來創(chuàng)建的?
- request提供了哪些API,這些API從哪里查?
首先,先看Request的繼承體系:
?
從上圖中可以看出,ServletRequest和HttpServletRequest都是Java提供的,所以我們可以打開JavaEE提供的API文檔查看:
?
?
所以ServletRequest和HttpServletRequest是繼承關系,并且兩個都是接口,接口是無法創(chuàng)建對象,這個時候就引發(fā)了下面這個問題:方法參數(shù)中傳遞的對象是由誰創(chuàng)建的
?
這個時候,就需要用到Request繼承體系中的RequestFacade:
- 該類實現(xiàn)了HttpServletRequest接口,也間接實現(xiàn)了ServletRequest接口。
- Servlet類中的service方法、doGet方法或者是doPost方法最終都是由Web服務器[Tomcat]來調(diào)用的,所以Tomcat提供了方法參數(shù)接口的具體實現(xiàn)類,并完成了對象的創(chuàng)建
- 要想了解RequestFacade中都提供了哪些方法,可以直接查看JavaEE的API文檔中關于ServletRequest和HttpServletRequest的接口文檔,因為RequestFacade實現(xiàn)了其接口就需要重寫接口中的方法
對于上述結(jié)論,要想驗證,可以編寫一個Servlet,在方法中把request對象打印下,就能看到最終的對象是不是RequestFacade,代碼如下:
@WebServlet("/demo2")
public class Demo2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(request);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
啟動服務器,運行訪問,得到運行結(jié)果:
?
小結(jié):
- Request的繼承體系為ServletRequest-->HttpServletRequest-->RequestFacade
- Tomcat需要解析請求數(shù)據(jù),封裝為request對象,并且創(chuàng)建request對象傳遞到service方法
- 使用request對象,可以查閱JavaEE API文檔的HttpServletRequest接口中方法說明
2、Request獲取請求數(shù)據(jù)
HTTP請求數(shù)據(jù)總共分為三部分內(nèi)容,分別是請求行、請求頭、請求體,對于這三部分內(nèi)容的數(shù)據(jù),分別該如何獲取,首先我們先來學習請求行數(shù)據(jù)如何獲取?
2.1、獲取請求行數(shù)據(jù)
請求行包含三塊內(nèi)容,分別是請求方式
、請求資源路徑
、HTTP協(xié)議及版本
?
對于這三部分內(nèi)容,request對象都提供了對應的API方法來獲取,具體如下:
- 獲取請求方式:
GET
->String getMethod()
- 獲取虛擬目錄(項目訪問路徑):
/Servlet
->String getContextPath()
- 獲取URL(統(tǒng)一資源定位符):
http://localhost:8080/Servlet/req1
->StringBuffer getRequestURL()
- 獲取URI(統(tǒng)一資源標識符):
/Servlet/req1
->String getRequestURI()
- 獲取請求參數(shù)(GET方式):
username=zhangsan&password=123
->String getQueryString()
介紹完上述方法后,下面通過代碼把上述方法都使用下:
package com.xzl.Request_Response;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author ︶ㄣ釋然* @date 2023/3/10 8:46* request 獲取請求數(shù)據(jù)*/
@WebServlet("/demo3")
public class Demo3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// String getMethod():獲取請求方式: GETString method = req.getMethod();System.out.println(method);//GET// String getContextPath():獲取虛擬目錄(項目訪問路徑)://ServletString contextPath = req.getContextPath();System.out.println(contextPath);// StringBuffer getRequestURL(): 獲取URL(統(tǒng)一資源定位符):http://localhost:8080/Servlet/demo3StringBuffer url = req.getRequestURL();System.out.println(url.toString());// String getRequestURI():獲取URI(統(tǒng)一資源標識符): /Servlet/demo3String uri = req.getRequestURI();System.out.println(uri);// String getQueryString():獲取請求參數(shù)(GET方式): name=ZiLin+XString queryString = req.getQueryString();System.out.println(queryString);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
啟動服務器,訪問http://localhost:8080/Servlet/demo3?name=ZiLin+X
,獲取的結(jié)果如下:
?
2.2、獲取請求頭數(shù)據(jù)
對于請求頭的數(shù)據(jù),格式為key: value
如下:
?
所以根據(jù)請求頭名稱獲取對應值的方法為:->String getHeader(String name)
接下來,在代碼中如果想要獲取客戶端瀏覽器的版本信息,則可以使用
/*** request 獲取請求數(shù)據(jù)*/
@WebServlet("/version")
public class version extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//獲取請求頭: user-agent: 瀏覽器的版本信息String agent = req.getHeader("user-agent");System.out.println(agent);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
重新啟動服務器后,獲取的結(jié)果如下:
?
2.3、獲取請求體數(shù)據(jù)
瀏覽器在發(fā)送GET請求的時候是沒有請求體的,所以需要把請求方式變更為POST,請求體中的數(shù)據(jù)格式如下:
?
對于請求體中的數(shù)據(jù),Request對象提供了如下兩種方式來獲取其中的數(shù)據(jù),分別是:
- 獲取字節(jié)輸入流,如果前端發(fā)送的是字節(jié)數(shù)據(jù),比如傳遞的是文件數(shù)據(jù),則使用該方法
ServletInputStream getInputStream() 該方法可以獲取字節(jié)
- 獲取字符輸入流,如果前端發(fā)送的是純文本數(shù)據(jù),則使用該方法
BufferedReader getReader()
接下來,需要思考,要想獲取到請求體的內(nèi)容該如何實現(xiàn)?
具體實現(xiàn)的步驟如下:
1.準備一個頁面,在頁面中添加form表單,用來發(fā)送post請求
2.在Servlet的doPost方法中獲取請求體數(shù)據(jù)
3.在doPost方法中使用request的getReader()或者getInputStream()來獲取
4.訪問測試
詳細步驟:
1、在項目的webapp目錄下添加一個html頁面,名稱為:req.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<!--action:form表單提交的請求地址method:請求方式,指定為post
-->
<form action="/Servlet/req1" method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit">
</form>
</body>
</html>
?2、在Servlet的doPost方法中獲取數(shù)據(jù)
調(diào)用getReader()或者getInputStream()方法,因為目前前端傳遞的是純文本數(shù)據(jù),所以我們采用getReader()方法來獲取
package com.xzl.Request_Response;/*** @author ︶ㄣ釋然* @date 2023/3/10 10:27*/import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;/*** request 獲取請求數(shù)據(jù)*/
@WebServlet("/req1")
public class req1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//在此處獲取請求體中的數(shù)據(jù)//獲取post 請求體:請求參數(shù)//1. 獲取字符輸入流BufferedReader br = req.getReader();//2. 讀取數(shù)據(jù)String line = br.readLine();System.out.println(line);}
}
?3、啟動服務器,通過瀏覽器訪問http://localhost:8080/Servlet/req.html
?
點擊提交
按鈕后,就可以在控制臺看到前端所發(fā)送的請求數(shù)據(jù)
?
注意
BufferedReader流是通過request對象來獲取的,當請求完成后request對象就會被銷毀,request對象被銷毀后,BufferedReader流就會自動關閉,所以此處就不需要手動關閉流了。
小結(jié)
HTTP請求數(shù)據(jù)中包含了請求行
、請求頭
和請求體
,針對這三部分內(nèi)容,Request對象都提供了對應的API方法來獲取對應的值:
- 請求行
- getMethod()獲取請求方式
- getContextPath()獲取項目訪問路徑
- getRequestURL()獲取請求URL
- getRequestURI()獲取請求URI
- getQueryString()獲取GET請求方式的請求參數(shù)
- 請求頭:getHeader(String name)根據(jù)請求頭名稱獲取其對應的值
- 請求體
- 注意: 瀏覽器發(fā)送的POST請求才有請求體
- 如果是純文本數(shù)據(jù):getReader()
- 如果是字節(jié)數(shù)據(jù)如文件數(shù)據(jù):getInputStream()
2.4、獲取請求參數(shù)的通用方式
在介紹下面內(nèi)容之前,先提出兩個問題:
- 什么是請求參數(shù)?
- 請求參數(shù)和請求數(shù)據(jù)的關系是什么?
1、什么是請求參數(shù)?
為了能更好的回答上述兩個問題,這里拿用戶登錄的例子來說明:
1.1 想要登錄網(wǎng)址,需要進入登錄頁面
1.2 在登錄頁面輸入用戶名和密碼
1.3 將用戶名和密碼提交到后臺
1.4 后臺校驗用戶名和密碼是否正確
1.5 如果正確,則正常登錄,如果不正確,則提示用戶名或密碼錯誤
上述例子中,用戶名和密碼其實就是所謂的請求參數(shù)。
2.什么是請求數(shù)據(jù)?
請求數(shù)據(jù)則是包含請求行、請求頭和請求體的所有數(shù)據(jù)
3.請求參數(shù)和請求數(shù)據(jù)的關系是什么?
3.1 請求參數(shù)是請求數(shù)據(jù)中的部分內(nèi)容
3.2 如果是GET請求,請求參數(shù)在請求行中
3.3 如果是POST請求,請求參數(shù)一般在請求體中
對于請求參數(shù)的獲取,常用的有以下兩種:
- GET方式->String getQueryString()
- POST方式->BufferedReader getReader();
練習一個案例需求:
(1)發(fā)送一個GET請求并攜帶用戶名,后臺接收后打印到控制臺
(2)發(fā)送一個POST請求并攜帶用戶名,后臺接收后打印到控制臺
此處大家需要注意的是GET請求和POST請求接收參數(shù)的方式不一樣,具體實現(xiàn)的代碼如下:
package com.xzl.Request_Response;/*** @author ︶ㄣ釋然* @date 2023/3/10 10:27*/import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;/*** request 獲取請求數(shù)據(jù)*/
@WebServlet("/req1")
public class req1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String result = req.getQueryString();System.out.println(result);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//在此處獲取請求體中的數(shù)據(jù)//獲取post 請求體:請求參數(shù)//1. 獲取字符輸入流BufferedReader br = req.getReader();//2. 讀取數(shù)據(jù)String line = br.readLine();System.out.println(line);}
}
- 對于上述的代碼,會存在什么問題呢?
由于請求方式不一樣,導致兩個方法中存在著大量重復代碼
- 如何解決上述重復代碼的問題?
?
需要注意的是,doGet和doPost方法都必須存在,不能刪除任意一個。
使用request的getMethod()來獲取請求方式,根據(jù)請求方式的不同分別獲取請求參數(shù)值,這樣就可以解決上述問題,但是以后每個Servlet都需要這樣寫代碼,實現(xiàn)起來比較麻煩,所以這種方法不采用。
更好的解決方案:
request對象已經(jīng)將上述獲取請求參數(shù)的方法進行了封裝,并且request提供的方法實現(xiàn)的功能更強大,以后只需要調(diào)用request提供的方法即可,在request的方法中都實現(xiàn)了哪些操作?
(1)根據(jù)不同的請求方式獲取請求參數(shù),獲取的內(nèi)容如下:
?
(2)把獲取到的內(nèi)容進行分割,內(nèi)容如下:
?
(3)把分割后端數(shù)據(jù),存入到一個Map集合中
注意:因為參數(shù)的值可能是一個,也可能有多個,所以Map的值的類型為String數(shù)組。
基于上述理論,request對象提供了如下方法:
- 獲取所有參數(shù)Map集合->Map<String,String[]> getParameterMap()
- 根據(jù)名稱獲取參數(shù)值(數(shù)組)->String[] getParameterValues(String name)
- 根據(jù)名稱獲取參數(shù)值(單個值)->String getParameter(String name)
接下來,通過案例來把上述的三個方法進行實例演示:
1.修改req.html頁面,添加愛好選項,愛好可以同時選多個
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="/Servlet/req2" method="get"><input type="text" name="username"><br><input type="password" name="password"><br><input type="checkbox" name="hobby" value="1"> 游泳<input type="checkbox" name="hobby" value="2"> 爬山 <br><input type="submit">
</form>
</body>
</html>
?
2.在Servlet代碼中獲取頁面?zhèn)鬟fGET請求的參數(shù)值 [完整代碼放在本小節(jié)2.2的最后]
2.1獲取GET方式的所有請求參數(shù)
?
獲取的結(jié)果為:
?
2.2獲取GET請求參數(shù)中的愛好,結(jié)果是數(shù)組值
?
獲取的結(jié)果為:
?
2.3、獲取GET請求參數(shù)中的用戶名和密碼,結(jié)果是單個值
?
獲取的結(jié)果為:
?
3.在Servlet代碼中獲取頁面?zhèn)鬟fPOST請求的參數(shù)值
3.1將req.html頁面form表單的提交方式改成post
3.2將doGet方法中的內(nèi)容復制到doPost方法中即可
?
2.5、完整代碼
package com.xzl.Request_Response;/*** @author ︶ㄣ釋然* @date 2023/3/10 17:39*/import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Map;/*** request 通用方式獲取請求參數(shù)*/
@WebServlet("/req2")
public class req2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//GET請求邏輯System.out.println("get....");//1. 獲取所有參數(shù)的Map集合Map<String, String[]> map = req.getParameterMap();for (String key : map.keySet()) {// username:XuZiLinSystem.out.print(key + ":");//獲取值String[] values = map.get(key);for (String value : values) {System.out.print(value + " ");}System.out.println();}//2、獲取GET請求參數(shù)中的愛好,結(jié)果是數(shù)組值System.out.println("-------------");String[] hobbies = req.getParameterValues("hobby");for (String hobby : hobbies) {System.out.println(hobby);}//3、獲取GET請求參數(shù)中的用戶名和密碼,結(jié)果是單個值String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(MessageFormat.format("username:{0}\npassword:{1}", username, password));}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("post....");this.doGet(req,resp);}
}
3、IDEA快速創(chuàng)建Servlet
由于一開始創(chuàng)建Servlet的時候,有一些代碼是固定要寫的,即有固定格式,那么可以通過IDEA來設置創(chuàng)建模板,從而實現(xiàn)快速創(chuàng)建。[可以根據(jù)自己的需求修改模板內(nèi)容]
?
使用Servlet模板創(chuàng)建模板類:
?
?
創(chuàng)建成功:
?
4、請求參數(shù)中文亂碼問題
不管是GET還是POST請求,在發(fā)送的請求參數(shù)中如果有中文,在后臺接收的時候,都會出現(xiàn)中文亂碼的問題。
4.1、🔺POST請求解決方案
分析出現(xiàn)中文亂碼的原因:
- POST的請求參數(shù)是通過request的getReader()來獲取流中的數(shù)據(jù)
- TOMCAT在獲取流的時候采用的編碼是ISO-8859-1
- ISO-8859-1編碼是不支持中文的,所以會出現(xiàn)亂碼
解決方案:
- 頁面設置的編碼格式為UTF-8
- 把Tomcat在獲取流數(shù)據(jù)之前的編碼設置為UTF-8
- 通過request.setCharacterEncoding("UTF-8")設置編碼,UTF-8也可以寫成小寫
重新發(fā)送POST請求,就會在控制臺看到正常展示的中文結(jié)果。
至此POST請求中文亂碼的問題就已經(jīng)解決,但是這種方案不適用于GET請求
4.2、🔺🔺GET請求解決方案
剛才提到一個問題是POST請求的中文亂碼解決方案為什么不適用GET請求?
- GET請求獲取請求參數(shù)的方式是
request.getQueryString()
- POST請求獲取請求參數(shù)的方式是
request.getReader()
- request.setCharacterEncoding("utf-8")是設置request處理流的編碼
- getQueryString方法并沒有通過流的方式獲取數(shù)據(jù)
所以GET請求不能用設置編碼的方式來解決中文亂碼問題
如何解決GET的編碼問題:
首先需要先分析下GET請求出現(xiàn)亂碼的原因:
?
(1)瀏覽器通過HTTP協(xié)議發(fā)送請求和數(shù)據(jù)給后臺服務器(Tomcat)
(2)瀏覽器在發(fā)送HTTP的過程中會對中文數(shù)據(jù)進行URL編碼
(3)在進行URL編碼的時候會采用頁面<meta>
標簽指定的UTF-8的方式進行編碼,張三
編碼后的結(jié)果為%E5%BC%A0%E4%B8%89
(4)后臺服務器(Tomcat)接收到%E5%BC%A0%E4%B8%89
后會默認按照ISO-8859-1
進行URL解碼
(5)由于前后編碼與解碼采用的格式不一樣,就會導致后臺獲取到的數(shù)據(jù)為亂碼。
補充兩個知識點:
URL編碼
具體編碼過程分兩步,分別是:
(1)將字符串按照編碼方式轉(zhuǎn)為二進制
(2)每個字節(jié)轉(zhuǎn)為2個16進制數(shù)并在前邊加上%
張三
按照UTF-8的方式轉(zhuǎn)換成二進制的結(jié)果為:
1110 0101 1011 1100 1010 0000 1110 0100 1011 1000 1000 1001
在Java中已經(jīng)提供了編碼和解碼的API工具類可以讓我們更快速的進行編碼和解碼:
編碼->java.net.URLEncoder.encode("需要被編碼的內(nèi)容","字符集(UTF-8)")
解碼->java.net.URLDecoder.decode("需要被解碼的內(nèi)容","字符集(UTF-8)")
接下來對張三
來進行編碼和解碼
public class URLDemo {public static void main(String[] args) throws UnsupportedEncodingException {String username = "張三";//1. URL編碼String encode = URLEncoder.encode(username, "utf-8");System.out.println(encode); //打印:%E5%BC%A0%E4%B8%89//2. URL解碼//String decode = URLDecoder.decode(encode, "utf-8");//打印:張三String decode = URLDecoder.decode(encode, "ISO-8859-1");//打印:`????? `System.out.println(decode);}
}
到這,我們就可以分析出GET請求中文參數(shù)出現(xiàn)亂碼的原因了:
- 瀏覽器把中文參數(shù)按照
UTF-8
進行URL編碼
- Tomcat對獲取到的內(nèi)容進行了
ISO-8859-1
的URL解碼
- 在控制臺就會出現(xiàn)類上
?? ??
的亂碼,最后一位是個空格
清楚了出現(xiàn)亂碼的原因,接下來提出解決辦法:
?
從上圖可以看出:
- 在進行編碼和解碼的時候,不管使用的是哪個字符集,他們對應的
%E5%BC%A0%E4%B8%89
是一致的
- 那他們對應的二進制值也是一樣的,為:
1110 0101 1011 1100 1010 0000 1110 0100 1011 1000 1000 1001
- 所以可以考慮把
?? ??
轉(zhuǎn)換成字節(jié),再把字節(jié)轉(zhuǎn)換成張三
,在轉(zhuǎn)換的過程中使它們的編碼一致,就可以解決中文亂碼問題。
具體的實現(xiàn)步驟為:
1.按照ISO-8859-1編碼獲取亂碼?? ??
對應的字節(jié)數(shù)組
2.按照UTF-8編碼獲取字節(jié)數(shù)組對應的字符串
實現(xiàn)代碼如下:
public class URLDemo {public static void main(String[] args) throws UnsupportedEncodingException {String username = "張三";//1. URL編碼String encode = URLEncoder.encode(username, "utf-8");System.out.println(encode);//2. URL解碼String decode = URLDecoder.decode(encode, "ISO-8859-1");System.out.println(decode); //此處打印的是對應的亂碼數(shù)據(jù)//3. 轉(zhuǎn)換為字節(jié)數(shù)據(jù),編碼byte[] bytes = decode.getBytes("ISO-8859-1");for (byte b : bytes) {System.out.print(b + " ");}//此處打印的是:-27 -68 -96 -28 -72 -119//4. 將字節(jié)數(shù)組轉(zhuǎn)為字符串,解碼String s = new String(bytes, "utf-8");System.out.println(s); //此處打印的是張三}
}
至此對于GET請求中文亂碼的解決方案,我們就已經(jīng)分析完了,最后在代碼中去實現(xiàn)下:
/*** 中文亂碼問題解決方案*/
package com.xzl.Request_Response; /*** @author ︶ㄣ釋然* @date 2023/3/10 18:49*/import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;@WebServlet("/GarbledCode")
public class GarbledCode extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);username = new String(bytes,StandardCharsets.UTF_8);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}
注意
- 在doPost沒有寫
request.setCharacterEncoding("UTF-8")
代碼的情況下,會發(fā)現(xiàn)GET請求參數(shù)亂碼解決方案同時也可也把POST請求參數(shù)亂碼的問題也解決了
- 只不過對于POST請求參數(shù)一般都會比較多,采用這種方式解決亂碼起來比較麻煩,所以對于POST請求還是建議使用設置編碼的方式進行。
另外需要說明一點的是Tomcat8.0之后,已將GET請求亂碼問題解決,設置默認的解碼方式為UTF-8
5、Request請求轉(zhuǎn)發(fā)
1、請求轉(zhuǎn)發(fā)(forward):一種在服務器內(nèi)部的資源跳轉(zhuǎn)方式。
?
(1)瀏覽器發(fā)送請求給服務器,服務器中對應的資源A接收到請求
(2)資源A處理完請求后將請求發(fā)給資源B
(3)資源B處理完后將結(jié)果響應給瀏覽器
(4)請求從資源A到資源B的過程就叫請求轉(zhuǎn)發(fā)
2、請求轉(zhuǎn)發(fā)的實現(xiàn)方式->req.getRequestDispatcher("資源B路徑").forward(req,resp);
具體如何使用:
?
針對上述需求,實現(xiàn)步驟為:
1.創(chuàng)建一個RequestDemo1類,接收/reqDemo1的請求
2.創(chuàng)建一個RequestDemo2類,接收/reqDemo2的請求
3.在RequestDemo1的方法中使用
req.getRequestDispatcher("/reqDemo2").forward(req,resp)進行請求轉(zhuǎn)發(fā)
4.啟動測試
具體實現(xiàn):
(1)創(chuàng)建RequestDemo1類
?
(2)創(chuàng)建RequestDemo2類
?
(3)在RequestDemo1的doGet方法中進行請求轉(zhuǎn)發(fā)
?
(4)啟動測試
?
可以看到請求已經(jīng)轉(zhuǎn)發(fā)成功了
3、請求轉(zhuǎn)發(fā)資源間共享數(shù)據(jù):使用request對象
此處主要解決的問題是把請求從/reqDemo1
轉(zhuǎn)發(fā)到/reqDemo2
的時候,如何傳遞數(shù)據(jù)給/reqDemo2
。
需要使用request對象提供的三個方法:
- 存儲數(shù)據(jù)到request域[范圍,數(shù)據(jù)是存儲在request對象]中:
void setAttribute(String name,Object o);
- 根據(jù)key獲取值
Object getAttribute(String name);
- 根據(jù)key刪除該鍵值對
void removeAttribute(String name);
下面是實現(xiàn)樣例:
1.在RequestDemo1的doGet方法中轉(zhuǎn)發(fā)請求之前,將數(shù)據(jù)存入request域?qū)ο笾?/p>
2.在RequestDemo2的doGet方法從request域?qū)ο笾蝎@取數(shù)據(jù),并將數(shù)據(jù)打印到控制臺
3.啟動訪問測試
(1)修改RequestDemo1中的方法
?
(2)修改RequestDemo2中的方法
?
(3)啟動測試
?
可以看到執(zhí)行成功了。
此時就可以實現(xiàn)在轉(zhuǎn)發(fā)多個資源之間共享數(shù)據(jù)。
4、請求轉(zhuǎn)發(fā)的特點
- 瀏覽器地址欄路徑不發(fā)生變化
雖然后臺從/reqDemo1
轉(zhuǎn)發(fā)到/reqDemo2
,但是瀏覽器的地址一直是/reqDemo1
,未發(fā)生變化
- 只能轉(zhuǎn)發(fā)到當前服務器的內(nèi)部資源
不能從一個服務器通過轉(zhuǎn)發(fā)訪問另一臺服務器
- 只能執(zhí)行一次請求,可以在轉(zhuǎn)發(fā)資源間使用request共享數(shù)據(jù)