HTTP 協定
什麼是HTTP 協定
什麼是協定?
協定是指雙方,或多方,互相約定好,大家都需要遵守的規則,叫協定。
所謂HTTP 協定,就是指,用戶端和伺服器之間通信時,發送的資料,需要遵守的規則,叫HTTP 協定。HTTP 協定中的資料又叫封包。
請求的HTTP 協定格式
用戶端給伺服器發送資料叫請求。
伺服器給用戶端回傳資料叫響應。
請求又分為GET 請求,和POST 請求兩種
GET 請求
-
請求行
(1) 請求的方式 ==> GET
(2) 請求的資源路徑 ==> [+?+請求參數]
(3) 請求的協定的版本号 ==> HTTP/1.1
-
請求頭
key : value 組成不同的鍵值對,表示不同的含義。
POST 請求
-
請求行
(1) 請求的方式POST
(2) 請求的資源路徑[+?+請求參數]
(3) 請求的協定的版本号HTTP/1.1
- 請求頭
-
key : value 不同的請求頭,有不同的含義
空行
- 請求體===>>> 就是發送給伺服器的資料
常用請求頭的說明
Accept: 表示用戶端可以接收的資料類型
Accpet-Languege: 表示用戶端可以接收的語言類型
User-Agent: 表示用戶端浏覽器的資訊
Host: 表示請求時的伺服器ip 和端口号
哪些是GET 請求,哪些是POST 請求
GET 請求有哪些:
1、form 标簽method=get
2、a 标簽
3、link 标簽引入css
4、Script 标簽引入js 檔案
5、img 标簽引入圖檔
6、iframe 引入html 頁面
7、在浏覽器位址欄中輸入位址後敲回車
POST 請求有哪些:
8、form 标簽method=post
響應的HTTP 協定格式
-
響應行
(1) 響應的協定和版本号
(2) 響應狀态碼
(3) 響應狀态描述符
-
響應頭
(1) key : value 不同的響應頭,有其不同含義
空行
- 響應體---->>> 就是回傳給用戶端的資料
常用的響應碼說明
200 表示請求成功
302 表示請求重定向
404 表示請求伺服器已經收到了,但是你要的資料不存在(請求位址錯誤)
500 表示伺服器已經收到請求,但是伺服器内部錯誤(代碼錯誤)
MIME 類型說明
MIME 是HTTP 協定中資料類型。
MIME 的英文全稱是"Multipurpose Internet Mail Extensions" 多功能Internet 郵件擴充服務。MIME 類型的格式是“大類型/小類型”,并與某一種檔案的擴充名相對應。
浏覽器如何檢視HTTP 協定:
按F12然後
HttpServletRequest 類
HttpServletRequest 類有什麼作用。
每次隻要有請求進入Tomcat 伺服器,Tomcat 伺服器就會把請求過來的HTTP 協定資訊解析好封裝到Request 對象中。然後傳遞到service 方法(doGet 和doPost)中給我們使用。我們可以通過HttpServletRequest 對象,擷取到所有請求的資訊。
HttpServletRequest 類的常用方法
方法名 | 作用 |
---|---|
| 擷取請求的資源路徑 |
| 擷取請求的統一資源定位符(絕對路徑) |
| 擷取用戶端的ip 位址 |
| 擷取請求頭 |
getParameter() | 擷取請求的參數(html的name) |
getParameterValues() | 擷取請求的參數(多個值的時候使用) |
getMethod() | 擷取請求的方式GET 或POST |
| 設定域資料 |
| 擷取域資料 |
getRequestDispatcher() | 擷取請求轉發對象 |
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// i.getRequestURI() 擷取請求的資源路徑
System.out.println("URI => " + req.getRequestURI());
// ii.getRequestURL() 擷取請求的統一資源定位符(絕對路徑)
System.out.println("URL => " + req.getRequestURL());
// iii.getRemoteHost() 擷取用戶端的ip位址
/**
* 在IDEA中,使用localhost通路時,得到的用戶端 ip 位址是 ===>>> 127.0.0.1<br/>
* 在IDEA中,使用127.0.0.1通路時,得到的用戶端 ip 位址是 ===>>> 127.0.0.1<br/>
* 在IDEA中,使用 真實ip 通路時,得到的用戶端 ip 位址是 ===>>> 真實的用戶端 ip 位址<br/>
*/
System.out.println("用戶端 ip位址 => " + req.getRemoteHost());
// iv.getHeader() 擷取請求頭
System.out.println("請求頭User-Agent ==>> " + req.getHeader("User-Agent"));
// vii.getMethod() 擷取請求的方式GET或POST
System.out.println( "請求的方式 ==>> " + req.getMethod() );
}
}
c)如何擷取請求參數
表單
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://localhost:8080/07_servlet/parameterServlet" method="post">
使用者名:<input type="text" name="username"><br/>
密碼:<input type="password" name="password"><br/>
興趣愛好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="js">JavaScript<br/>
<input type="submit">
</form>
</body>
</html>
代碼案例
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("-------------doGet------------");
// 擷取請求參數
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby");
System.out.println("使用者名:" + username);
System.out.println("密碼:" + password);
System.out.println("興趣愛好:" + Arrays.asList(hobby));
}
}
doGet 請求的中文亂碼解決:
// 擷取請求參數
String username = req.getParameter("username");
//1 先以iso8859-1進行編碼
//2 再以utf-8進行解碼
username = new String(username.getBytes("iso-8859-1"), "UTF-8");
POST 請求的中文亂碼解決
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 設定請求體的字元集為UTF-8,進而解決post請求的中文亂碼問題
// 也要在擷取請求參數之前調用才有效
req.setCharacterEncoding("UTF-8");
System.out.println("-------------doPost------------");
// 擷取請求參數
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby");
System.out.println("使用者名:" + username);
System.out.println("密碼:" + password);
System.out.println("興趣愛好:" + Arrays.asList(hobby));
}
請求的轉發
什麼是請求的轉發?
請求轉發是指,伺服器收到請求後,從一次資源跳轉到另一個資源的操作叫請求轉發。
Servlet1 代碼:
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 擷取請求的參數(辦事的材料)檢視
String username = req.getParameter("username");
System.out.println("在Servlet1(櫃台1)中檢視參數(材料):" + username);
// 給材料 蓋一個章,并傳遞到Servlet2(櫃台 2)去檢視
req.setAttribute("key1","櫃台1的章");
// 問路:Servlet2(櫃台 2)怎麼走
/**
* 請求轉發必須要以斜杠打頭,/ 斜杠表示位址為:http://ip:port/工程名/ , 映射到IDEA代碼的web目錄<br/>
*
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
// RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com");
// 走向Sevlet2(櫃台 2)
requestDispatcher.forward(req,resp);
}
}
Servlet2 代碼:
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 擷取請求的參數(辦事的材料)檢視
String username = req.getParameter("username");
System.out.println("在Servlet2(櫃台2)中檢視參數(材料):" + username);
// 檢視 櫃台1 是否有蓋章
Object key1 = req.getAttribute("key1");
System.out.println("櫃台1是否有章:" + key1);
// 處理自己的業務
System.out.println("Servlet2 處理自己的業務 ");
}
}
base 标簽的作用
base 标簽設定頁面相對路徑工作時參照的位址
web 中/ 斜杠的不同意義
在web 中/ 斜杠是一種絕對路徑。
/ 斜杠如果被浏覽器解析,得到的位址是:http://ip:port/
<a href="/" target="_blank" rel="external nofollow" >斜杠</a>
/ 斜杠如果被伺服器解析,得到的位址是:http://ip:port/工程路徑
1、
<url-pattern>/servlet1</url-pattern>
2、
servletContext.getRealPath(“/”);
3、
request.getRequestDispatcher(“/”);
特殊情況:
response.sendRediect(“/”);
把斜杠發送給浏覽器解析。得到http://ip:port/
HttpServletResponse 類
HttpServletResponse 類的作用
HttpServletResponse 類和HttpServletRequest 類一樣。每次請求進來,Tomcat 伺服器都會建立一個Response 對象傳遞給Servlet 程式去使用。HttpServletRequest 表示請求過來的資訊,HttpServletResponse 表示所有響應的資訊,我們如果需要設定傳回給用戶端的資訊,都可以通過HttpServletResponse 對象來進行設定
兩個輸出流的說明。
位元組流getOutputStream(); 常用于下載下傳(傳遞二進制資料)
字元流getWriter(); 常用于回傳字元串(常用)
兩個流同時隻能使用一個。
使用了位元組流,就不能再使用字元流,反之亦然,否則就會報錯。
如何往用戶端回傳資料
要求: 往用戶端回傳字元串資料。
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 要求: 往用戶端回傳字元串資料。
PrintWriter writer = resp.getWriter();
writer.write("response's content!!!");
}
}
響應的亂碼解決
解決響應中文亂碼方案一(不推薦使用):
// 設定伺服器字元集為UTF-8
resp.setCharacterEncoding("UTF-8");
// 通過響應頭,設定浏覽器也使用UTF-8 字元集
resp.setHeader("Content-Type", "text/html; charset=UTF-8");
解決響應中文亂碼方案二(推薦):
// 它會同時設定伺服器和用戶端都使用UTF-8 字元集,還設定了響應頭
// 此方法一定要在擷取流對象之前調用才有效
resp.setContentType("text/html; charset=UTF-8");
請求重定向
請求重定向,是指用戶端給伺服器發請求,然後伺服器告訴用戶端說。我給你一些位址。你去新位址通路。叫請求重定向(因為之前的位址可能已經被廢棄)。
請求重定向的第一種方案:
// 設定響應狀态碼302 ,表示重定向,(已搬遷)
resp.setStatus(302);
// 設定響應頭,說明新的位址在哪裡
resp.setHeader("Location", "http://localhost:8080");
請求重定向的第二種方案(推薦使用):
注意
web-inf是安全目錄
還是由浏覽器通路資源,通路不到web-inf
如果由server通路是可以的