HTTP協議
- HTTP:超文本傳輸協議,定義了瀏覽器與服務器之間數據傳輸的格式;簡而言之,就是一種在web中傳輸數據的格式。
- HTTP協議組成:
- 請求報文:請求行,請求頭,請求體;
- 請求行:請求報文中的第一行數據,包括請求方式,URL,協議/版本;
- 請求頭:以鍵值對的數據格式,給服務器傳輸數據。常用的請求頭:user-agent,cookie;
- 請求體:get請求:沒有請求體;post請求:請求體傳遞請求參數;
- GET:向特定的資源發出請求(a href="servlet"標籤/js location.href=“servlet”)
- POST向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的創建和/或已有資源的修改
- 響應報文:響應行,響應頭,響應體;
- 請求報文:請求行,請求頭,請求體;
百科:HTTP協議
超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最爲廣泛的一種網絡協議。
所有的WWW文件都必須遵守這個標準。設計HTTP最初的目的是爲了提供一種發佈和接收HTML頁面的方法。
1960年美國人TedNelson構思了一種通過計算機處理文本信息的方法,並稱之爲超文本(hypertext),這成爲了HTTP超文本傳輸協議標準架構的發展根基。
Ted Nelson組織協調萬維網協會(World Wide Web Consortium)和互聯網工程工作小組(Internet Engineering Task Force )共同合作研究,最終發佈了一系列的RFC,其中著名的RFC 2616定義了HTTP 1.1
協議版本:
HTTP/1.0,發送請求,創建一次連接,獲得一個web資源,連接斷開。
HTTP/1.1,發送請求,創建一次連接,獲得多個web資源,連接斷開。
GET和POST請求區別
GET請求:
請求行直接傳遞請求參數
將請求參數追加在URL後面,不安全。例如:form.html?username=jack&username=1234
URL長度限制GET請求方式的數據大小,不可以傳輸數據量較大或者非文本數據
請求體裏面沒有內容
POST請求
請求參數以請求體形式發送給服務器,數據傳輸安全
請求數據可以爲非文本數據,可以傳輸數據量較大的數據
只有表單設置爲method=”post”纔是post請求.其他的都是get請求, 常見GET請求:地址欄直接訪問、< a href=””>、< img src=””> 等
瀏覽器和服務器是以固定的格式進行通信的,採取的HTTP協議的請求協議。瀏覽器通過請求協議,將數據傳送到服務器中。
request與請求數據的獲取
通過request對象可以獲取請求攜帶的數據,分別獲取請求行、請求頭、請求體中的數據,從而獲取用戶提交的數據,進行業務邏輯的處理。
什麼是HttpServletRequest
HttpServletRequest對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求中的所有信息都封裝在這個對象中,我們通過這個對象的方法,可以獲得客戶這些信息。
HTTPServletRequest的作用
通過Request對象進行的常用操作:
- 獲取請求行信息:請求方式,url和HTTP版本;
- 獲取去請求頭信息:瀏覽器類型,cookie等;
- 獲取請求參數:url後面拼接的參數或者請求體中提交的參數;
獲取請求行信息
請求行包括:請求方式,url和協議版本。HttpServletRequest對象提供了以下方法來獲取這些信息。
- String getMethod():獲取去請求方式的類型。
- StringBuffer getRequestURL():獲取客戶端發出請求完整URL。
- String getRemoteAddr():獲取IP地址。
- String getProtocol():獲取當前協議的名稱和版本。
代碼:
@WebServlet("/rowServlet")
public class RowServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//請求行API
//獲取請求協議版本號
String protocol = request.getProtocol();
System.out.println("protocol = " + protocol);
//獲取請求方式
String method = request.getMethod();
System.out.println("method = " + method);
//IP地址
String remoteAddr = request.getRemoteAddr();
System.out.println("remoteAddr = " + remoteAddr);
//獲取URL
StringBuffer requestURL = request.getRequestURL();
System.out.println("requestURL = " + requestURL);
}
}
獲取請求頭信息
瀏覽器的請求頭信息是由很多:關鍵字:值 形式的數據組成的。HttpServletRequest對象給我們提供了兩個方法用來獲取請求的頭信息。
- String getHeader(String name):根據請求頭的k關鍵字獲取請求頭信息。
- Enumeration getHeaderNames():返回此請求包含的所有頭信息的枚舉。
請求頭的k關鍵字如下表所示:
代碼:
@WebServlet("/headerServlet")
public class HeaderServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//獲取請求頭API
String header = request.getHeader("User-Agent");
System.out.println("header = " + header);
//獲取所有key
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()){
System.out.println(headerNames.nextElement());
}
}
}
獲取請求體(請求參數)(很重要)
學習了請求航和請求頭的內容,然後就是請求體了,在請求體中,包含的是用戶通過瀏覽器發送的請求參數,因此,我們主要學習的就是獲取請求參數的方法。
回顧一下瀏覽器中的請求數據是怎麼提交的。
get請求:提交的數據是拼接在url後面。
post請求:數據是在請求體中發送到後臺的。
兩者的格式都是name=value
獲取請求參數的方法
- String getParameter(String name):getParameter獲得指定參數名對應的值。如果沒有返回null,如果有多個則獲取第一個。例如username=jack。
- String[ ] getParameterValues(name):getParameterValues[ ]獲取請求數據key相同的多個數據。
- request.getParameterMap():獲取所有表單數據。
代碼:
編寫用戶表單,提供表單字段:username、password、hobby、以post方式提交。
(由於沒有設置utf-8,大家在提交數據時,儘量別用中文)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="requestServlet" method="post">
用戶名:<input type="text" name="username"/><br/>
密碼:<input type="text" name="password"/><br/>
愛好:<input type="checkbox" name="hobby"value="smoking"/> 抽菸
<input type="checkbox" name="hobby"value="drinking"/> 喝酒
<input type="checkbox" name="hobby" value="tangtou"/> 燙頭 <br/>
學歷:<select name="education">
<option value="gaozhong">高中</option>
<option value="dazhuan">大專</option>
<option value="benke">本科</option>
</select><br>
<input type="submit"value="post提交" />
</form>
</body>
</html>
@WebServlet("/requestServlet")
public class RequestServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//獲取用戶提交的所有數據
String username=request.getParameter("username");
System.out.println("用戶提交的所有數據:useranme:"+username);
String password=request.getParameter("password");
System.out.println("-------------------password:"+password);
String[] hobbies=request.getParameterValues("hobby");
System.out.println("-------------------hobby:"+Arrays.toString(hobbies));
//可以獲取表單提交所有信息
Map<String,String[]> parameterMap=request.getParameterMap();
Collection<String[]> values=parameterMap.values();
for (String[] value:values){
System.out.println(Arrays.toString(value));
}
}
}
request作用域
request的生命週期
【一次請求和響應的完整流程】
1、瀏覽器向servlet發送請求
2、tomcat收到請求後,創建Request和Response兩個對象,並將請求數據封裝到request對象中,然後傳遞給Servlet
3、Servlet接收到請求後,調用request提供的方法。處理瀏覽器的請求信息,然後通過Response返回信息
4、tomcat將業務邏輯處理的結果,返回給瀏覽器。
5、瀏覽器接收到返回消息後,tomcat銷燬Request和Response兩個對象,同時銷燬這兩個對象所獲得的信息。
- 創建:瀏覽器給服務器發送請求後,tomcat創建request對象封裝請求數據;
- 銷燬:服務器給瀏覽器響應信息結束後銷燬;
特點:瀏覽器每次給服務器發送請求,服務器都會爲這次請求創建一個request對象。
request域對象
request域對象,一個存儲數據的區域對象.是把request當成一個容器來存儲數據,request域存儲數據主要是用於在兩個servlet之間傳遞數據。request作爲域對象,常用的方法如下:
- void setAttribute(String name,Object o):往request域中設置值。
- Object getAttribute(String name):從request域中取值。
- void removeAttribute(String name):從request域中刪除值。
演示:
創建一個servlet
往request域中設置值
從request域中取值
將request域中的值移除
@WebServlet("/value")
public class ValueServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用request對象存儲值
request.setAttribute("key","關曉彤");
//根據KEY 來獲取值
String key = (String) request.getAttribute("key");
System.out.println("美女 = " + key);
//移除值
request.removeAttribute("key");
Object key1 = request.getAttribute("key");
if (key1==null){
System.out.println("刪除成功");
}
}
}
注意:getParameter()方法和getAttribute()方法的區別
- getParameter()方法獲取的是瀏覽器提交的數據(多是表單提交的數據);
- getAttribute()方法是獲取request域中的數據(通過request.setAttribute()設置的值;
請求轉發:
我們之前使用到的請求都是從頁面發出,然後請求到Servlet。其實,在Servlet中。請求也可以從一個Servlet發起,然後請求到另一個Servlet或靜態頁面。這項技術叫做請求轉發。
請求轉發需要藉助以下兩個方法實現:
- RequestDispatcher getRequestDispatcher(String path):獲取請求轉發器(request對象方法)
- void forward(ServletRequest request, ServletResponse response):將請求轉發到另一個資源(Servlet)上
演示:請求轉發
需求:
從一個Servlet轉發到另一個Servlet;
從一個Servlet轉發到一個靜態頁面;
@WebServlet("/twoServlet")
public class TwoServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//通過request域對象設置值
//使用轉發 其他servlet
req.setAttribute("name","xiaoming");
//避免代碼臃腫
//獲取請求轉發器
req.getRequestDispatcher("/thrServlet").forward(req,resp);
}
}
@WebServlet("/thrServlet")
public class ThrServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//獲取數據,進行處理
String name=(String)req.getAttribute("name");
System.out.println("name="+name);
}
}
從servlet轉發到html
@WebServlet("/oneServlet")
public class OneServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//靜態資源
//使用轉發
req.getRequestDispatcher("/one.html").forward(req,resp);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>關曉彤</h1>
</body>
</html>
轉發:
- 轉發是服務器內部的跳轉行爲;
- 從一個Servlet轉發到另一個資源(靜態或者動態),能夠實現跳轉,但是瀏覽器地址欄沒有改變,因爲對瀏覽器來說,本質上只有一個請求。
- 請求轉發的作用:共享request域中的數據。
登錄案例
需求:
- 設計登錄表單頁面,數據庫用戶表user (字段 id,userName,password),通過sql手動插入若干用戶數據記錄。
- 基於form表單數據提交,將客戶端用戶輸入的賬號和密碼發送給服務器Servlet
- Servlet獲取表單提交的賬號和密碼數據,基於所學的JdbcTemplate直接訪問數據庫t_user表,查詢賬號和密碼是否正確
- 根據數據庫查詢的結果,如果賬號密碼錯誤,轉發到error.html。賬號密碼都正確轉發到success.html頁面。
搭建環境:
。