Web-Servlet(1)
獲取引數
大致流程

- 在WEB-INF同級下新建一個html檔案,寫一個表單
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<form action="add" method="post">
名稱<input type="text" name="fname"/><br>
價格<input type="text" name="price"/><br>
庫存<input type="text" name="fcount"/><br>
備注<input type="text" name="remake"/><br>
<input type="submit" value="https://www.cnblogs.com/wht-de-bk/p/添加"/><br>
</form>
</body>
</html>
- 在src下新建一個類(AddSevlet)

注:要匯入一個包:servlet-api,jar或是點擊專案結構
找到自己建額專案

再這樣

找到紅線畫的
//這里要添一點包哦
public class AddServlet extends HttpServlst{
@Override
public void doPost(HttpServletRequest request,HttpServletResponse response)throws IOExcepton,ServletExcption{
String fname = request.getParameter("fname");
String priceSrc = https://www.cnblogs.com/wht-de-bk/p/request.getParameter("price");
Integer price = Integer.parseInt(priceSrc); //強轉一下
String fcountSrc = https://www.cnblogs.com/wht-de-bk/p/request.getParameter("fcount");
Integer fcount = Integer.parseInt(fcountSrc);
String remake = request.getParameter("remake");
System.out.println("fanme="+fname);
System.out.println("price="+price);
System.out.println("fcount="+fcount);
System.out.println("remake="+remake);
}
}
- 再在WEB-INF下新建xml組態檔
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>AddServlet</servlet-name>
<servlet-class>com.servlet.AddServlet</servlet-class> <!--要寫全哦-->
</servlet>
<servlet-mapping>
<servlet-name>AddServlet</servlet-name>
<url-pattern>/add</url-pattern>
</servlet-mapping>
</web-app>
基本流程/步驟
<!--
1.用戶發請求,action = add
2.服務器(tomcat)/專案,中web.xml中找到url-pattern = /add
3.找到第11行的servlet-name = AddServlet
4.找和servlet-mapping中servlet-name一致的servlet
5.找到第八行的servlet-class = com.servlet.AddServlet
6.用戶發送的post請求(method = post) 因此tomcat會執行AddServlet中的doPost方法
-->
然后執行,如果看了上一篇的視頻,并跟的做了的話可能會出現,404

沒有關系將之前的Demo01改成自己html檔案的名字就可以啦

再點擊添加后,就可以再控制臺看到這個了

Servlet的小基礎
設定編碼問題
- 案例:
在上個專案中的水果表單添加中文時會出現亂碼

- 解決方法
在AddServlet中添加(tomcat8之后)
request.setCharacterEncoding("UTF-8");
注:這句代碼要在獲取引數之前來填寫
解決啦

Servlet的繼承關系
繼承關系(重點查看服務方法)
java.servlet.Servlet介面
java.servlet.GenericServlet抽象類
java.servlet.http.HttpServlet抽象子類
相關方法
- java.servlet.Servlet介面
void init(config) --初始化方法
void service(request,response) --服務方法
void destory() -- 銷毀方法
- java.servlet.GenericServlet抽象類
void service(request,response) -- 仍然是抽象的
- java.servlet.http.HttpServlet抽象子類
void service(request,response) --不是抽象的
1.String method = req.getMethood() -- 獲取請求的方式
2.各種if判斷,根據請求方式的不同,決定去呼叫不同的do方法
3.在HttpServlet這個抽象類中,do方法都差不多
小結
- 繼承關系:HttpServlet->GrnericsServlet->Servlet
- Servlet中的核心方法:init(),service(),destory()
- 服務方法:當有請求過來時,service方法會自動回應(其實時tomcat容器呼叫的)
- 在HttpServlet中我們會分析請求的方式,是get,post,head...然后決定呼叫那個方法(默認405實作風格--要我們子類去實作對應的方法,否則報405錯誤)
- 新建Servlet時,我們要考慮請求方法,從而決定重寫哪個do方法
Servlet的生命周期
- 生命周期的概念:從出生到死亡的程序,對應Servlet中3個方法init(),service(),destory()
來個小例子
- html中
//演示Servlet的生命周期
public class Servlet02 extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("正在初始化...");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("正在服務...");
}
@Override
public void destroy() {
System.out.println("正在銷毀");
}
}
- web.xml中
<servlet>
<servlet-name>Servlet02</servlet-name>
<servlet-class>src.com.servlets.Servlet02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet02</servlet-name>
<url-pattern>/Demo02</url-pattern>
</servlet-mapping>
看看效果:

-
默認情況下:
- 第一次接收請求時,這個Servlet會進行實體化(呼叫構造方法),初始化(呼叫init()),然后服務(呼叫service()) *提高 服務器的啟動速度,第一次請求耗時較長* - 從第二次請求開始,每一次都是服務(點一下重繪,服務一次) - 當容器關閉時,其中的所有的Servlet實體化會被銷毀,呼叫銷毀方法 -
Servlet實體tomcat只會創建一個,所有的請求都是這個實體去回應
因此:如果要提高系統的啟動速度,當前默認情況就是這樣;如果需要提高回應速度,我們應該設定Servlet的初始化時機
-
Servlet在容器中是,單例的,執行緒不安全的(共用一個實體)
-單例:所有請求都是同一個實體去回應
-執行緒不安全:一個執行緒需要根據這個實體中的某個成員變數的值去做邏輯判斷,但是在中間某個時機,另一個執行緒 改變了這個成員變數的值,導致第一個執行緒的執行路徑發生了變化
-盡量不要在Servlet中定義成員變數,如果要定義,不要去根據成員便改良的值去做邏輯判斷 / 修改成員變數的值

Servlet的初始化時機
默認是第一次接收請求時,實體化,初始化
我們可以通過
修改之后

Http協議
介紹
-
Http:Hyper Text transfer Protocol超文本傳輸協議,確定了請求和回應的資料格式
-
Http是無狀態的
-
Http請求回應包含兩個部分:請求和回應
-請求:請求包含3個部分:1.請求行 2.請求(訊息)頭 3.請求體 -回應:回應也含3個部分:1.回應行 2.回應(訊息)頭 3.回應體
請求
請求行
作用:展現當前請求的最基本資訊
- 請求方式
- 訪問地址
- HTTP協議的版本
在我剛才的頁面上可以查看(F12)

請求(訊息)頭
作用:通過具體的引數對本次請求進行詳細說明(包含很多客戶端需要告訴服務器的資訊,eg:我的瀏覽器型號、版本...)
格式:鍵值對,鍵和值之間只用""隔開

請求體
作用:作為請求的主體,發送資料給服務器,具體來說其實就是POS請求方法下的請求引數
格式:
- get方式,沒有請求體,但是有一個queryString
- post方式,有請求體,form data
- josn格式,有請求體,request payload
回應
回應行
- 協議
- 回應狀態碼
- 回應狀態
回應(訊息)頭
包含服務器資訊:服務器發送給瀏覽器的資訊(內容的媒體型別、編碼...)
回應體
回應的實際內容(eg:請求html的內容)
會話
解釋Http無狀態:服務器無法判斷兩次(或多次)請求是否是同一個客戶端發來的
-實際問題:第一次請求時添加商品到購物車,第二次時結賬,若無法區分是否時同一用戶發的請求,會導致混亂
-通過會話跟蹤技術來解決
會話跟蹤技術

- 客戶端第一次發請求給服務器,服務器獲取session,獲取不到,則創建一個新的,然后回應給客戶端
- 下次客戶端給服務器發請求時,會把sessionID帶給服務器,那么服務器就能獲取到了,服務器就判斷這一次和某次請求時同分異構客戶端發出的,來區分客戶端
- 常用的API
request.getSessin() -> 獲取當前的會話,沒有創一個新的
request.getSession(true) -> 同上
request.getSession(false) -> 獲取當前會話,沒有則回傳null,不會創建新的
session.getId() -> 獲取sessionID
session,isNew -> 判斷當前session是否是新的
session.getMaxInactiveIntervsl() -> session的非激活間隔時長(默認1800s)
session.setMaxInactiveIntervsl()
session.invalidata() -> 強制讓會話立即失效
session.get
小例子(web.xml就不寫了,都一樣)
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取session,如果獲取不到,則創鍵一個新的
HttpSession session = req.getSession();
System.out.println("sessionID:"+session.getId());
}

session保存作用域

1.session保存作用域是和具體的某一個session對應的
2.常用的API
//可以有多個key,但不要重復,一旦重復,會覆寫之前的value
void session.setAttribute(k,v);
Object session.getAttribute(k);
void removeAttribute(k);
大家如果不想實驗代碼就先跳過下面這一段
兩個不同的類哦
//session保存作用域:存盤
public class Servlet04 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getSession().setAttribute("uname","lina");
}
//session保存作用域:獲取(它是Demo05)
public class Servlet05 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object unameObj = request.getSession().getAttribute("uname");
System.out.println("unameObj:"+unameObj);
}
同上web.xml就不寫了
最后會在控制臺輸出 lina(可以嘗試換一個瀏覽器搜索Demo05,結果是null哦)
服務器內部轉發和客戶端重定向
- 服務器內部轉發:req.getRequestDispatcher("...").forward(req,resp);

-是一次請求回應的程序,對于客戶端,內部經歷了多少次轉發,客戶端時不知道的
-地址欄沒有變化
例子:(注意看紅色的線)

- 客戶端重定向:resp.sendRedirect("...");

-兩次請求回應的程序,客戶端知道URL有變化
-地址欄有變化
例子:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/455548.html
標籤:Java
