服務器
web應用的演變
倆層CS架構
? 特點:資料庫作為server,使用其特定的編程語言,撰寫業務邏輯,客戶端提供操作頁面和少量的業務邏輯
? 缺點:移植性較差,更換資料庫時需要重新編程,不適合大型應用
三層CS架構
? 特點:資料庫只負責資料的管理;應用服務器提供所有的業務邏輯處理;客戶端只負責操作界面
? 優點:移植性好,適合大型應用
? 缺點:客戶端需要單獨安裝(限制),開發復雜(需要自定義協議,撰寫客戶端和服務器的通信模塊)
BS架構
特點:資料庫只負責資料管理;應用服務器提供所有的業務邏輯處理;客戶端只負責操作界面
? 優點:不需要單獨安裝客戶端,開發相對于CS簡單,客戶端與服務端都是使用標準的HTTP協議
Servlet
Sun(Oracle)公司制定的一種用來擴展web服務器功能的組件規范
擴展web服務器功能:
? 早期的web服務端只能處理靜態資源請求,無法根據請求計算后生成相應的HTML頁面,但是Servlet可以完成這一個需求,Servlet需要滿足一種規范(Servlet運行環境)Tomcat就是一個容器(服務器),提供了Servlet的運行環境
組件規范:
? Servlet是一個組件,符合一定的規范,實作部分的功能,并且需要部署到容器中才能運行的軟體模組
容器:符合一定規范,提供組件運行環境的一個程式
Servlet作業流程
文字總結:瀏覽器根據IP建立與容器的連接,瀏覽器將請求資料打包發送給服務器,服務器接收到后進行拆包,決議請求資料包,封裝物件,容器依據路徑找到Servlet路徑創建物件,然后呼叫Servlet的service()方法,從respose中獲取結果,然后將其進行打成回應資料包,然后通過HTTP協議發送給瀏覽器,瀏覽器進行決議執行在客戶端進行顯示
Servlet運行中常見的錯誤以及解決方法:
數字錯誤是服務器執行完客戶端的請求后,回傳給客戶端執行結果的狀態編碼,當執行正確時也會回傳數字200;
404錯誤:
產生原因:web服務器根據請求地址找不到對應的資源
可能情況:
- 地址寫錯,拼寫錯誤
- web.xml檔案中的倆個的名字不一致
- 工程沒有部署
- web應用程式結構沒有遵循Servlet規范
405錯誤:
產生原因:web服務器找不到service()方法
可能情況:
- Service方法名稱寫錯
- Service方法引數型別與標準不一致
- Service方法例外,回傳值型別與標準不一致
500錯誤:
可能原因:程式運行程序中出錯
可能情況:
- servlet類沒有繼承HttpServlet或實作servlet介面
- web.xml中的寫錯
- service方法代碼運行時拋出例外
地址格式
請求地址格式:
http://ip:port/project_name/url-pattern
http://localhost:8088/Servlet2008/demo1
請求資源路徑:
/project_name/url-pattern
/Servlet2008/demo1
Servlet路徑:
/url-pattern
/demo1
HTTP協議(Hyper Text Transfer Protocol):
由W3C制定的一種應用層協議,用來定義瀏覽器和服務器之間如何通信以及通信的資料格式
請求資料包:
請求行:請求方式+請求資源路徑+協議版本
訊息頭:是一些鍵值對,通訊的雙方通過訊息頭來傳遞一些特定的含義
物體內容:只有當請求為post時,物體內容才會有資料(請求引數)
回應資料包:
狀態行:協議版本+狀態碼+狀態描述
訊息頭:web服務器回傳一些訊息頭給客戶端,例如回傳content-type告訴瀏覽器,服務器回傳的資料型別以及字符集
物體內容:程式處理的結果
Servlet如何處理HTTP協議:
Servlet如何控制通信資料:
當web服務器收到HTTP請求時,通信資料由web容器負責封裝和提供這些資訊被解釋成倆個物件
-
與請求資料對應的是HttpServletRequest物件
當客戶端通過Http協議訪問服務器時,請求中的所有訊息都能封裝到這個物件中
? 作用:讀取或寫入Http請求資料;獲取和設定cookie;取得路徑資訊;標識Http會話;實作請求轉發
-
與回應資料對應的是HttpServletResponse物件
當服務器通過http協議提供給客戶端時,回應中的所有訊息都會封裝到物件中
? 作用:設定對客戶端的輸出內容;設定回應的狀態碼;設定瀏覽器的解碼方式;設定cookie;實作重定向
Servlet如何接收請求引數:
? getParameter()方法:
? 常用于傳入的引數中,一個名字對應一個值的形式
String request.getParameter(String name);
? getParameterValues()方法:
? 當需要獲取引數名相同的多個引數值時使用該方法,用于獲取提交表單中的復選框的值,如引數名寫錯,會產生null
String[ ] request.getParameterValues(String name);
請求方式:get、post
get請求:當需要向服務器請求指定的資源時使用的方法
? 什么情況下瀏覽器發送get請求:在瀏覽器地址欄輸入一個地址;點擊連接(類似于超鏈接)
post請求:向服務器提交需要處理的資料,這些資料寫在請求資料包的物體內容中
表單:
向服務器提交需要處理的資料,表單的默認請求方式為get請求,會將請求資料添加到請求資源的后面,只有提交少量資料,并顯示在瀏覽器地址欄上,不安全
只有將表單的method屬性改為post,才會發送post,請求引數添加到物體內容中,可提交大量資料,不會將請求引數顯示在地址欄上,相對安全
Servlet如何處理中文引數:
為什么表單提交中會出現亂碼:當表單提交時,瀏覽器會對中文引數值進行編碼(會使用打開表單所在頁面時的字符集進行編碼)服務器在默認情況下會使用ISO-8859-1去解碼,當編碼和解碼不一致時會出現亂碼
解決post方式時的亂碼問題:
-
確保表單所在的頁面按照指定的字符集打開
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -
在服務端繼續按照這個編碼格式去解碼,必須添加在讀取資料之前,只針對post有效
request.setCharacterEncoding("utf-8")
解決get方式時的亂碼問題:
-
確保表單所在頁面按照制定的字符集打開
-
進行轉譯
String name = request.getParameter(“name”); name = new String(name.getBytes(“iso-8859-1”),”utf-8”);
如何輸出中文:
response.setContentType(“text/html;charset=utf-8”)
Servlet容器如何處理請求資源路徑(/projectName/xxx):
服務器對請求地址的處理程序:
- 瀏覽器根據IP建立與Servlet容器之間的連接,然后將請求資源路徑發送給容器
- 容器根據應用名(projectName)找到應用所在的檔案,容器默認為請求為一個Servlet,會去在web.xml中查找所有的Servlet配置中的節點看是否有匹配的servlet,若沒有則在當前應用下查找是否存在對應頁面
匹配規則:
優先級:精確匹配 > 后綴匹配 > 通配符匹配
-
精確匹配
通過將請求資源路徑中的具體名稱與web.xml中的進行比對,嚴格匹配相等后找到對應的資源并執行;盡管應用中有當前所需的頁面,但是也會執行的servlet
-
通配符匹配
使用"/*"來匹配0或者多個字符
<url-pattern>/*</url-pattern> /ServletEmp/addEmp.html // 匹配成功 /ServletEmp/abc/a/f/gg/hh/kk/addEmp //匹配成功 -
后綴匹配
不能使用/開頭,使用“*.xx”開頭的任意多個字符
<url-pattern>*.do</url-pattern> //會匹配所有以.do結尾的請求 -
無匹配
如果精確匹配,后綴匹配,通配符匹配都未匹配成功,容器會查找到對應的檔案后回傳,若找不到則回傳404錯誤
一個Servlet如何實作多請求(mvc思想):
為什么要合并多個Servlet:
? 一般情況下Servlet的主要作用是充當控制器的角色即接收請求并分發給不同的資源,這時servlet只要有 一個就可以完成分發請求的程序
實作合并的步驟:
- 使用后綴或者通配符匹配模式修改web.xml
- 獲取請求資源路徑(uri)分析具體的請求資源后,依據分支結構的不同呼叫不同的分支進行處理
重定向
服務器向瀏覽器發送一個302狀態碼以及一個location訊息頭(該訊息頭的值是一個地址,稱之為重定向的地址),瀏覽器收到后立即向重定向的地址發送請求
如何進行重定向:
response.sendRedirect(String url)
重定向的特點:
- 重定向的地址是任意地址
- 重定向后地址欄發生改變
- 重定向程序中涉及的web組件不會共享一對request和response物件
- 重定向的程序中發送倆次請求
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZdrsHPfJ-1613106133522)(C:\Users\Melody\AppData\Roaming\Typora\typora-user-images\image-20210208153141422.png)]
Servlet生命周期
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dWwyZuTh-1613106133529)(C:\Users\Melody\AppData\Roaming\Typora\typora-user-images\image-20210208160305179.png)]
生命周期的四個階段:
第一階段:實體化(Servlet構造方法):
什么是實體化:容器呼叫Servlet構造器,創建一個Servlet物件
什么適合實體化:
- 開始時容器中并沒有Servlet物件,只有收到請求后才會創建Servlet物件
- 當在中加入1更改優先級后,容器會在啟動之后立即創建servlet物件
第二階段:初始化(init方法):
? 什么是初始化:容器在創建好servlet物件后會立即呼叫物件的init方法,一般情況下不用寫init方法,它會自己實作,init方法只會執行一次
? 容器在創建好Servlet物件后還會創建一個ServletConfig物件,用來讀取在web.xml中內部配置的內的初始化資訊,然后將ServletConfig物件作為引數傳遞給init方法,從而進行初始化操作
第三階段:就緒(呼叫Service()方法)
? 實體化,初始化結束后,Servlet容器呼叫Service()方法,進行業務處理
第四階段:銷毀(destroy()方法):
? 處理結束后,容器根據自身演算法洗掉Servlet物件,洗掉前會呼叫destroy()方法,并且只會執行一次
ServletContext:
什么是Servlet背景關系:
容器啟動后會為每一個web應用創建唯一的一個符合ServletContext介面要求的物件,該物件就是servelt背景關系
特點:
- 唯一性:一個web應用對應一個Servlet
- 一直存在:只要容器不關閉,應用沒有卸載,Servlet背景關系就一直存在
如何獲得Servlet背景關系:
- 通過ServletConfig提供的getServletContext();
- 通過HttpSession提供的getServletContext();
- 通過FilterConfig提供的getServletContext();
Servlet背景關系的作用及特點:
- 使用setAttribute()系結資料
- 使用removeAttribute移除系結的資料
- 使用getAttribute獲取系結的資料
特點:Servlet背景關系系結的資料可以被整個應用上的所有組件共享,并且可以一直訪問
//獲取全域背景關系物件
ServletContext application = getServletContext();
Object count = application.getAttribute("count");
if(count == null){
//application.setAttribute("count",1);
application.setAttribute("count",
application.getInitParameter("count"));
}else{
application.setAttribute("count",Integer.parseInt(count.toString())+1);
}
out.println("<h1>當前瀏覽量為:"+application.getAttribute("count")+"</h1>");
JSP的由來:Servlet技術產生之后再使用時最大的麻煩在于使用大量的out.println()陳述句輸出頁面,這樣的形式再系統變更,維護,預覽效果時都不能方便快捷的完成任務,于是JSP應用而生,用來將Servlet中負責顯示的陳述句抽離出來
什么是JSP?
SUN(Oracle)公司制定的一種服務端動態頁面技術的組件規范,JSP是以.jsp為后綴的檔案,在讀檔案中,主要是以HTML和少量的JAVA代碼,JSP檔案會被容器轉換為一個Servlet類,然后執行,JSP的本質上依據是Servlet
JSP語法規范:
如何撰寫JSP:
- 寫一個以.jsp為后綴的檔案
- 該檔案中可以包含:HTML(css,javascript),注釋,JAVA代碼,指令,隱含(內置)物件
JSP頁面中的HTML代碼:
? HTML標記,CSS,javascript在jsp中撰寫方式與HTML中的一樣
? 作用:控制頁面在瀏覽器中的顯示效果
? 轉譯成Servlet的規則:成為Servlet中service()方法的out.println()方法
JS頁面中的注釋:
HTML注釋
? 注釋的內容如果包含java代碼,這些代碼不會被注釋
? 語法規則:
JSP特有的注釋
? 其中若有Java代碼,則會被注釋,不會編譯
? 語法規則:<%-- 內容 – %>
JSP頁面的Java代碼:
? 三種表示:JSP運算式,JSP小腳本,JSP宣告
? 撰寫位置:頁面的任意位置
? 作用:控制頁面中可變內容的產生
JSP運算式
? 語法規則:<%= 內容 %>
? 合法內容:變數,變數加運算子組成的運算式,有回傳值的方法
? 轉譯成Servlet的規則:在Service()方法中用out.println()陳述句輸出的該變數,運算式以及方法的回傳值
JSP小腳本
? 語法規則:<% 內容 %>
? 合法內容:能夠寫在方法里的Java代碼都可以作為小腳本
? 轉譯成Servlet規則:原封不動成為Servlet中的Service()方法里的一段代碼
JSP宣告
? 語法規則:<%! 內容 %>
? 合法內容:成員屬性以及成員方法的宣告
? 轉譯成Servlet規則:成為Servlet類中的成員屬性或成員方法
JSP頁面中的指令:
語法規則:<%@ 指令名 屬性=值%>
常用指令:page,include,taglib指令
作用:控制JSP在轉譯成Servlet類時生成的內容
Page指令:
用于導包,設定頁面屬性
語法:<%@ page import=”url”%>
Include指令:
在JSP頁面轉譯成Servlet時,能夠將其他檔案包含進來,可以包含動態的jsp檔案,也可以是靜態的HTML檔案
語法:<%@ include file =”url”%>
隱含物件(內置物件)
在啟動時容器自動創建,在JSP檔案中可以直接使用的物件
作用:JSP預先創建的這些物件可以簡化為對HTTP物件,回應資訊的方法
| 輸入輸出物件 | request,response,out |
|---|---|
| 作用域通信物件 | Session,application,pageContext |
| Servlet | page,config |
| 例外物件 | exception |
| 內置物件 | 型別 | 說明 |
|---|---|---|
| request | HttpServletRequest | 請求資訊 |
| response | HttpServletResponse | 回應資訊 |
| out | JspWriter | 輸出資料流 |
| Session | HttpSession | 會話 |
| pageContext | pageContext | 頁面背景關系 |
| application | Application | 全域背景關系 |
| config | ServletConfig | Servlet配置物件 |
| Exception | Throwable | 捕獲網頁例外 |
JSP運行原理
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NSVrnr39-1613106133533)(C:\Users\Melody\AppData\Roaming\Typora\typora-user-images\image-20210209110444374.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-KRyZSvzD-1613106133537)(C:\Users\Melody\AppData\Roaming\Typora\typora-user-images\image-20210209110536171.png)]
如何將靜態頁面轉為動態頁面
- 拷貝靜態頁面代碼到JSP
- 添加page指令
- 修改頁面內容與目標頁面一致
- 將需要動態生成的內容洗掉轉為Java代碼
轉發
什么是轉發?
一個web組件(Servlet/jsp)將未完成的處理通過容器轉交給另一個組件繼續完成
常規情況:
? 一個servlet組件獲取資料之后(比如呼叫dao)將這些資料轉發給一個JSP,由這些JSP展現這些資料的頁面
如何實作轉發?
-
系結資料到request物件
實作系結:request.setAttribute(String name,Object obj) 讀取系結:Object request.getAttribute(String) 其系結后結果回傳值是object類需要進行強轉為所轉換的型別 若系結名不存在,回傳為null -
獲得轉發器
RequestDispatcher rd = request .getRequestDispatcher(String uri) uri:為轉發的目的地,將未完成的處理繼續下去的另一個組件 -
轉發
rd.forward(request,response)通常情況下2,3步可以合并
request.getRequestAttribute(String uri).forward(request,respons)
轉發的特點:
- 轉發之后瀏覽器地址欄發生不發生改變(原因:轉發程序發生在服務器內部,并沒有跟瀏覽器進行互動,瀏覽器不知情)
- 轉發的目的地必須是同一應用(同一工程)內的某個位置
- 轉發所涉及的多個web組件共享一對request,response物件
轉發與重定向的區別:
- 重定向是瀏覽器發出請求并收到回應后再次向一個新的地址發送請求;轉發是服務器收到請求后為了完成回應轉發到一個新的地址
- 重定向中有多次請求物件,不共享資料;轉發則只產生一次請求物件且在組件內共享資料
- 重定向后瀏覽器的地址欄發生改變,轉發不會改變
- 重定向的新地址可以是任意地址,轉發的新地址則必須是同一個應用內的某個地址
例外處理
編程式例外處理
使用轉發進行跳轉指定頁面提示說明
在try-catch塊中,當catch塊中出現例外時跳轉到指定頁面,而不會出現報錯界面,比如500錯誤等等
容器宣告式例外處理
-
將例外拋給容器
-
在web.xml中配置錯誤處理的頁面節點
<!-- 配置錯誤處理頁面 --> <error-page> <exception-type>javax.servlet.ServletException </exception-type> <location>/error.jsp</location> </error-page> -
Notice:例外只允許拋出service()方法指定的ServiceExecption和IOExecption例外,不能拋出指定范圍以外的例外
不同例外處理方式的應用場景
? 對于程式本身的例外最好使用編程式的處理方法,如空指標例外
? 對于系統級別的例外最好使用容器宣告式的方式,如資料庫連不上
路徑
什么是路徑?
鏈接地址<a href="url">
表單提交:<form action="url">
重定向:response.sendReadirect(url)
轉發:reuqest.getRequestDispatcher(url)
什么是相對路徑?
從當前檔案出發到達目的地檔案所經過的路徑稱為相對路徑
書寫格式不以“/”開頭,回傳上一級目錄以“…/”開頭
什么是絕對路徑?
以“/”開頭的路徑是絕對路徑,不以當前位置做起始,而是以一個固定的位置作為起始到達目標檔案所經過的路徑
路徑的使用技巧
在使用絕對路徑時:鏈接地址,表單提交,重定向從應用名開始寫,轉發則是從應用名之后開始寫
狀態管理
為什么要狀態管理?
Web應用程式使用的是HTTP協議,而HTTP協議是“無狀態”協議,即服務器一旦回應完客戶的請求之后,就斷開連接,而同一個客戶的下一次請求將重新建立網路連接,服務器應用程式有時是需要判斷是否為同一個客戶發出的多次請求
什么是狀態管理?
將客戶端與服務器之間的多次互動(一次請求一次回應)當作一個整體并且將多次互動所涉及的資料即狀態保存下來
狀態指的是資料
管理指的是多次互動產生的對資料的修改
狀態管理常見的倆種技術
客戶端的狀態管理技術:將狀態保存在客戶端,例如Cookie
服務器的狀態管理技術:將狀態保存在服務端,例如Session
Cookie
瀏覽器向web服務器發送請求時,服務器將少量的資料以set-cookie的形式發送給瀏覽器,瀏覽器將這些保存下來
當瀏覽器再次訪問服務器時,會將這些資料以cookie訊息頭的方式發送給服務器
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rGjXvrwh-1613106133541)(C:\Users\Melody\AppData\Roaming\Typora\typora-user-images\image-20210209113443339.png)]
如何創建Cookie
Servlet API提供了javax.servlet.http.Cookie
Cookie c = new Cookie(String name , String value);
response.addCookie(c);
如何查詢Cookie
獲取客戶端的所有Cookie物件 Cookie[] request.getCookie()
獲取一個或多個Cookie物件的名稱和值 String cookie.getName(); String cookie.getValue();
如何修改cookie?
- 獲取客戶端發送的所有cookie
- 根據name找到要修改的cookie
- 呼叫cookie的setValue(String newValue)方法修改該cookie 的值
- 將修改后的cookie添加到response.addCookie()中
Cookie的生存時間
默認情況下,瀏覽器會將cookie保存在記憶體中,只要瀏覽器不關閉,cookie就一致存在
若希望關閉瀏覽器cookie仍存在,則需要設定過期時間
void cookie setMaxAge(int seconds) 單位為秒
seconds>0, cookie保存的指定時間
seconds=0,洗掉cookie
seconds<0,相當于默認情況
Cookie編碼
只能保存合法的ASCII字符,如需要保存中文,則需要將其轉成ASCII字符,即編碼
Cookie c =new Cookie(“city”,URLEncoder.encode(“北京”,“utf-8”))
Cookie解碼
編碼后的Cookie為看到實際中文,需要還原后在現實
URLDecode.decode(value,”utf-8”);
Cookie的路徑問題
瀏覽器在訪問服務器上的某個地方時,會比較cookie的路徑與該路徑是否匹配,只有匹配的cookie才能發送給服務器
Cookie的默認路徑等于添加這個cookie的web組件路徑
–如:/appName/file/addCookie.jsp添加了一個Cookie,此時Cookie的路徑等于/appName/file
發送cookie的條件:要訪問的地址必須是cookie的路勁或者其子路徑,瀏覽器才會發送cookie
如何設定cookie路徑:
Cookie c = new Cookie(“unane”,jack)
c.sePath(“/appname”)
respnse.addCookie(c)
Cookie的限制:
Cookie可以被用戶禁止
Cookie會將狀態保存在瀏覽器端,不安全,對于敏感的資料需要加密之后在使用cookie保存
Cookie只能保存少量資料,大約4kb
Cookie的個數是有限制的
Cookie只能保存字串
Session
什么是Session(會話)?
瀏覽器訪問web服務器時,服務器會為每一個瀏覽器在服務器的記憶體中分配空間,單獨創建一個Session物件,該物件有一個ID屬性,其值唯一,一般稱之為SessionId,并且服務器將這個SessionId(使用cookie方式)發送給瀏覽器,瀏覽器再次訪問服務器時,會將SessionID發送給服務器,服務器根據SessionID找到對應的Session物件
如何獲取Session?
HttpSession request.getSession(boolean flag)
HttpSession是一個介面,后面回傳的是符合介面規范的物件
當flag=true,先查看請求,若沒有SessionID,服務器會創建一個新的Session物件;若有SessionID,依據其SessionId可以找到對應的Session物件,則回傳,若根據SessionID找不到Session物件,則立即創建,即flag=true時,一定能得到一個Session物件
當flag=false時,沒有SessionID或有SessionID但是找不到Session物件,均回傳為null,找到則回傳
requset.getSession() 等價于request.getSession(true),提供該方法是為了書寫方便,無論找到或者沒找到,都需要回傳一Session物件
如何使用Seesion來系結物件
系結: void Session.setAttribute(String name,Object obj)
獲取: Object Session.getAttribute(String name)
移出: void Session.removeAttribute(String name)
如何洗掉Session物件
立即洗掉: Session :Session.invalidate()
Session驗證
用戶訪問需要保護的資源時,可以使用Session驗證的方式來保證其安全性,比如登陸驗證,首先使用Session.setAttribute()系結資料,然后使用Session.getAttribute()方法來讀取系結值,如沒有則回傳登陸頁面
Session超時
Web服務器會將空閑時間長的Session物件洗掉,以便節省服務器記憶體空間,默認空閑時間為30min
如何修飾Session的有效時間
-
? 容器宣告式配置:在web.xml內進行配置
<session-config> <session-timeout>30</session-timeout> 分鐘 </session-config> -
? 編程式配置:利用代碼進行配置
Session.setMaxInactiveInterval(60)秒
瀏覽器禁用cookie的后果
如過瀏覽器禁用cookie后,Session還能用么?
? 答:不能用,但是有其他解決辦法,服務器默認情況下會使用cookie的方式將SessionId發送給瀏覽器,如果禁用 cookie,則Sessionid不會被瀏覽器保存,此時服務器可以使用URL重寫的方式發送Sessionid
什么是URL重寫?
瀏覽器在訪問服務器上的某個地址時,不在按原來的那個地址而是使用經過重寫的地址(即在原來的地址后加上SessionId)
如何重寫URL?
? 若是鏈接地址和表單提交:response.EncodeURL(String uri)
? 若是重定向:response.encodeReadirectURL(String url)
Session的優缺點
優點:
- 安全性(將狀態保存在服務器)
- Session能夠保存的資料型別更加豐富,cookie只能是字串
- Session能夠保存更多的資料,cookie大約只能保存4kb
缺點: Session將狀態保存在服務端,占用服務器的記憶體,如果用戶量過大,嚴重影響服務器的性能
過濾器
什么是過濾器?
過濾器是Servlet規范定義中定義的一種小型的可插入的web組件,用來攔截Servlet的請求和回應程序以便查看,提取或以某種方式操作操作正在客戶端和服務端之間互動的資料
過濾器通常是封裝了一些功能的web組件,這些功能很重要,但是對于客戶端請求或發送回應來說不是決定向的
如何撰寫過濾器?
- 撰寫一個Java類,實作Filter介面
- 在doFilter方法中實作過濾(攔截)處理邏輯,將過濾器添加到web程式中
- 然后將過濾器和web組件一起打包部署
多個過濾器
如果有多個過濾器都滿足過濾請求,則容器依據<filter-mapping>的先后順序,來呼叫各個過濾器一次執行
<filter>
<filter-name>MyFilter1</filter-name>
<filter-class>org.oracle.filter.MyFilter1</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter1</filter-name>
<url-pattern>/conment</url-pattern>
</filter-mapping>
過濾器的優點
實作代碼的“可插拔性”,即增加或減少某個功能模塊,不會影響程式的正常執行,可以將多個相同處理邏輯的模塊集中寫在過濾器里面,方便代碼維護
監聽器
什么是監聽器?
Servlet規范中定義的一種特殊組件,用來監聽Servlet容器產生的事件并進行相應的處理
容器產生的倆大類事件:生命周期相關事件,系結資料相關事件
生命周期相關事件
在創建,銷毀request,session,ServletContext時產生的事件
ServletRequestListener:
? 創建:requestInitlized(ServletRequestEvent sre)
? 銷毀:requestDestoryed(ServletRequestEvent sre)
HttpSessionListener
? 創建:sessionCreated(HttpSessionEvent se)
? 銷毀:sessionDestoryed(HttpSessionEvent se)
ServletContextListener
? 創建:contextInitlized(servletContextEvent sce)
? 銷毀:contextDestoryed(servletContextEvent sce)
系結資料相關事件
容器呼叫request,session,ServletContext物件的setAttribute,removeAttribute方法時產生的事件
ServletRequestAttributeListener
AttributeAdded(requestAttribute srae)
如何撰寫監聽器?
撰寫一個java類,在依據監聽事件型別選擇實作相應的監聽介面,在監聽器的介面方法中,實作相應的監聽處理邏輯,在web.xml中注冊監聽器
web.xml中配置
<listener>
<listener-class>org.oracle.listener.CountSessionListener</listener-class>
</listener>
EL與JSTL
為什么需要EL運算式和JSP標簽?
JSP中嵌套大量的JAVA代碼增加了頁面的復雜度,使頁面不夠整潔,不方便代碼維護,為此Sun公司(Oracle)指定JSP標簽(類似HTML標簽)代替JAVA代碼
Apache組織開發的一套標簽被Sun公司整合,稱之為標準標簽庫(JSTL)配合EL運算式,以達到減輕JSP檔案的復雜度,方便維護JSP檔案的目的
什么是EL運算式?
是一套簡單的計算規則,用于給JSP標簽賦值,也可以直接用來輸出,其也可以單獨使用
EL運算式的作用:訪問Bean的屬性;輸出簡單的運行結果;獲取請求引數
使用EL訪問Bean屬性
方法一:${物件名.屬性名}
方法二:${物件名[“屬性名”]}
執行程序:容器會依次從pageContext,request,Session,application中查找系結名稱為“user”物件,找到后呼叫“getName”方法輸出
即${user.name}等價于pageContext/request/session/application.getAttributr(“user”)
User.getName();若上面沒有user物件,會報500錯誤,若找到但未給name賦值,則輸出為null
指定物件的查找范圍
在撰寫EL運算式時,可以指定查找對于系結名物件的范圍,一旦制定了范圍,那么在該范圍內沒有找到物件時,則不會去其他區域找
即${sessionScope.user.name}在指定的session中尋找
使用EL運算式獲取請求引數值
${param.name}等價于request.getParameter(“name”);
${paramValues.city}等價于request.getParamenterValues(“city”);
使用EL運算式進行運算
EL運算式可以做一些簡單計算,可以將結果直接輸出
算數運算(“+”只能求和,不能做字串拼接),邏輯運算,關系運算
JSTL
JSP的標準標簽庫,JSP標簽是sun公司定義的一套標準,后將Apache整合
如何使用JSTL?
將JSTL標簽對應的jar檔案引入當前環境,使用taglib指令匯入要使用的JSP標簽
<% taglib uri=”” prefix=”” %>,其中uri:jsp標簽的命名空間;prefix:命名空間的前綴
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
核心標簽
①語法:<c:if test=”” var=”” scope=”” ></c:if>
當test屬性值為true時,執行標簽體的內容,test屬性可以使用EL運算式賦值;var屬性:指定一個系結名稱;scope屬性:指定系結的范圍(pageContext,request,session,application);var和scope聯合進行使用
②語法:
<c:choose>
<c:when test=””></c:when>
...
<c:otherwise></c:otherwise>
</c:choose>
when表示一個處理分支,當test屬性為true時,執行該分支,可出現一次或者多次;otherwise:表示列外,可出現0次或一次
③用來遍歷集合或陣列
語法:<c:forEach items=” ” var=””></c:forEach>
<c:forEach var="emp" items="${list }">
<tr>
<td>${emp.id }</td>
<td>${emp.name }</td>
<td>${emp.age }</td>
</tr>
</c:forEach>
Items:指定要遍歷的陣列和集合,使用EL運算式賦值
Var:指定一個系結名稱,容器每次從集合中取出一個物件,系結到pagaContext中
Varstatus:指定一個系結名稱,系結值為一個容器創建的物件,該物件分裝了當前的迭代狀態
Index:回傳被正在迭代物件的下標,下標從0開始
Count:回傳第幾次迭代,從1開始
AJAX
Ajax屬于客戶端和服務端互動的一種技術,全稱為Asynchronous JavaScript and XML(JSON),即異步的javascript和xml
原有的互動模式:(整個頁面回應+請求回應)
瀏覽器發送請求 --> Tomcat服務器 --> Tomcat將將回應資訊給瀏覽器 --> 瀏覽器顯示回應結果
Ajax互動模式:(區域重繪+異步加載)
瀏覽器發送請求 --> XMLHttpRequest發送 --> Tomcat服務器 --> Tomcat回傳結果 --> XMLHttpRequest接受結果 --> 將結果顯示到瀏覽器頁面
XMLHttpRequset屬性
①readyState:0,1,2,3,4
? 0:未初始化 – 尚未呼叫.open()方法;
? 1:啟動 – 已經呼叫.open()方法,但尚未呼叫.send()方法;
? 2:發送 – 已經呼叫.send()方法,但尚未接收到回應;
? 3:接收 – 已經接收到部分回應資料;
? 4:完成 – 已經接收到全部回應資料,而且已經可以在客戶端使用了
? 創建-初始化請求-發送請求-接收資料-決議資料-完成
②responseText:獲取服務器回傳的文本資訊
③responseXML:獲取服務器回傳的XML資訊
④status:Http的回應狀態:200 請求成功 ;202 請求被接受但處理未完成 ;400 錯誤請求 ;404 請求資源未找到 ;500 內部服務器錯誤
JQuery·Ajax
$ajax({}) --> XMLHttpRequset
$ajax({
? Url:請求地址,
? Type:請求型別get/post,
? Data:提交的資料,
? Async:同步或異步處理true/false,
? DataType:預期服務器回傳的資料型別,
? Success:成功回呼函式,
? Error:失敗回呼函式,
? BeforeSend:請求發送回呼函式 });
面對需求考慮思維:觸發事件源 → 觸發事件時機 → 執行什么操作
回傳第幾次迭代,從1開始
AJAX
Ajax屬于客戶端和服務端互動的一種技術,全稱為Asynchronous JavaScript and XML(JSON),即異步的javascript和xml
原有的互動模式:(整個頁面回應+請求回應)
瀏覽器發送請求 --> Tomcat服務器 --> Tomcat將將回應資訊給瀏覽器 --> 瀏覽器顯示回應結果
Ajax互動模式:(區域重繪+異步加載)
瀏覽器發送請求 --> XMLHttpRequest發送 --> Tomcat服務器 --> Tomcat回傳結果 --> XMLHttpRequest接受結果 --> 將結果顯示到瀏覽器頁面
XMLHttpRequset屬性
①readyState:0,1,2,3,4
? 0:未初始化 – 尚未呼叫.open()方法;
? 1:啟動 – 已經呼叫.open()方法,但尚未呼叫.send()方法;
? 2:發送 – 已經呼叫.send()方法,但尚未接收到回應;
? 3:接收 – 已經接收到部分回應資料;
? 4:完成 – 已經接收到全部回應資料,而且已經可以在客戶端使用了
? 創建-初始化請求-發送請求-接收資料-決議資料-完成
②responseText:獲取服務器回傳的文本資訊
③responseXML:獲取服務器回傳的XML資訊
④status:Http的回應狀態:200 請求成功 ;202 請求被接受但處理未完成 ;400 錯誤請求 ;404 請求資源未找到 ;500 內部服務器錯誤
JQuery·Ajax
$ajax({}) --> XMLHttpRequset
$ajax({
? Url:請求地址,
? Type:請求型別get/post,
? Data:提交的資料,
? Async:同步或異步處理true/false,
? DataType:預期服務器回傳的資料型別,
? Success:成功回呼函式,
? Error:失敗回呼函式,
? BeforeSend:請求發送回呼函式 });
面對需求考慮思維:觸發事件源 → 觸發事件時機 → 執行什么操作
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/259488.html
標籤:其他
上一篇:Codeforces 1485D - Multiples and Power Differences (構造)
下一篇:郵件模板如何開發?
