Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】
Servlet的調(diào)用圖
前面我們已經(jīng)學(xué)過(guò)了Servlet的生命周期了,我們根據(jù)Servlet的生命周期畫(huà)出Servlet的調(diào)用圖加深理解
Servlet的細(xì)節(jié)
一個(gè)已經(jīng)注冊(cè)的Servlet可以被多次映射
同一個(gè)Servlet可以被映射到多個(gè)URL上。
<servlet><servlet-name>Demo1</servlet-name><servlet-class>zhongfucheng.web.Demo1</servlet-class></servlet><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>/Demo1</url-pattern></servlet-mapping><servlet-mapping><servlet-name>Demo1</servlet-name><url-pattern>/ouzicheng</url-pattern></servlet-mapping>無(wú)論我訪問(wèn)的是http://localhost:8080/Demo1還是http://localhost:8080/ouzicheng。我訪問(wèn)的都是Demo1。
Servlet映射的URL可以使用通配符
通配符有兩種格式:
匹配所有
匹配擴(kuò)展名為.jsp的
如果.擴(kuò)展名和正斜杠(/)開(kāi)頭并以“/”結(jié)尾兩種通配符同時(shí)出現(xiàn),匹配的是哪一個(gè)呢?
Servlet映射的URL可以使用通配符和Servlet可以被映射到多個(gè)URL上的作用:
Servlet是單例的
為什么Servlet是單例的
瀏覽器多次對(duì)Servlet的請(qǐng)求,一般情況下,服務(wù)器只創(chuàng)建一個(gè)Servlet對(duì)象,也就是說(shuō),Servlet對(duì)象一旦創(chuàng)建了,就會(huì)駐留在內(nèi)存中,為后續(xù)的請(qǐng)求做服務(wù),直到服務(wù)器關(guān)閉。
每次訪問(wèn)請(qǐng)求對(duì)象和響應(yīng)對(duì)象都是新的
對(duì)于每次訪問(wèn)請(qǐng)求,Servlet引擎都會(huì)創(chuàng)建一個(gè)新的HttpServletRequest請(qǐng)求對(duì)象和一個(gè)新的HttpServletResponse響應(yīng)對(duì)象,然后將這兩個(gè)對(duì)象作為參數(shù)傳遞給它調(diào)用的Servlet的service()方法,service方法再根據(jù)請(qǐng)求方式分別調(diào)用doXXX方法。
線程安全問(wèn)題
當(dāng)多個(gè)用戶訪問(wèn)Servlet的時(shí)候,服務(wù)器會(huì)為每個(gè)用戶創(chuàng)建一個(gè)線程。當(dāng)多個(gè)用戶并發(fā)訪問(wèn)Servlet共享資源的時(shí)候就會(huì)出現(xiàn)線程安全問(wèn)題。
原則:
load-on-startup
如果在元素中配置了一個(gè)元素,那么WEB應(yīng)用程序在啟動(dòng)時(shí),就會(huì)裝載并創(chuàng)建Servlet的實(shí)例對(duì)象、以及調(diào)用Servlet實(shí)例對(duì)象的init()方法。
作用:
在web訪問(wèn)任何資源都是在訪問(wèn)Servlet
當(dāng)你啟動(dòng)Tomcat,你在網(wǎng)址上輸入http://localhost:8080。為什么會(huì)出現(xiàn)Tomcat小貓的頁(yè)面?
這是由缺省Servlet為你服務(wù)的!
- 我們先看一下web.xml文件中的配置,web.xml文件配置了一個(gè)缺省Servlet
- 什么叫做缺省Servlet?凡是在web.xml文件中找不到匹配的元素的URL,它們的訪問(wèn)請(qǐng)求都將交給缺省Servlet處理,也就是說(shuō),缺省Servlet用于處理所有其他Servlet都不處理的訪問(wèn)請(qǐng)求
- 既然我說(shuō)了在web訪問(wèn)任何資源都是在訪問(wèn)Servlet,那么我訪問(wèn)靜態(tài)資源【本地圖片,本地HTML文件】也是在訪問(wèn)這個(gè)缺省Servlet【DefaultServlet】
- 證實(shí)一下:當(dāng)我沒(méi)有手工配置缺省Servlet的時(shí)候,訪問(wèn)本地圖片是可以訪問(wèn)得到的
- 現(xiàn)在我自己配置一個(gè)缺省Servlet,Demo1就是我手工配置的缺省Servlet,覆蓋掉web.xml配置的缺省Servlet
- 下面我繼續(xù)訪問(wèn)一下剛才的圖片,此時(shí)輸出的是Demo1這個(gè)Servlet寫(xiě)上的內(nèi)容了
- 總結(jié):無(wú)論在web中訪問(wèn)什么資源【包括JSP】,都是在訪問(wèn)Servlet。沒(méi)有手工配置缺省Servlet的時(shí)候,你訪問(wèn)靜態(tài)圖片,靜態(tài)網(wǎng)頁(yè),缺省Servlet會(huì)在你web站點(diǎn)中尋找該圖片或網(wǎng)頁(yè),如果有就返回給瀏覽器,沒(méi)有就報(bào)404錯(cuò)誤
ServletConfig對(duì)象
ServletConfig對(duì)象有什么用?
通過(guò)此對(duì)象可以讀取web.xml中配置的初始化參數(shù)。
現(xiàn)在問(wèn)題來(lái)了,為什么我們要把參數(shù)信息放到web.xml文件中呢?我們可以直接在程序中都可以定義參數(shù)信息,搞到web.xml文件中又有什么好處呢?
好處就是:能夠讓你的程序更加靈活【更換需求,更改配置文件web.xml即可,程序代碼不用改】
獲取web.xml文件配置的參數(shù)信息
- 為Demo1這個(gè)Servlet配置一個(gè)參數(shù),參數(shù)名是name,值是zhongfucheng
- 在Servlet中獲取ServletConfig對(duì)象,通過(guò)ServletConfig對(duì)象獲取在web.xml文件配置的參數(shù)
ServletContext對(duì)象
什么是ServletContext對(duì)象?
當(dāng)Tomcat啟動(dòng)的時(shí)候,就會(huì)創(chuàng)建一個(gè)ServletContext對(duì)象。它代表著當(dāng)前web站點(diǎn)
ServletContext有什么用?
Servlet之間實(shí)現(xiàn)通訊
ServletContext對(duì)象可以被稱之為域?qū)ο?/strong>
到這里可能有一個(gè)疑問(wèn),域?qū)ο笫鞘裁茨?#xff1f;其實(shí)域?qū)ο罂梢院?jiǎn)單理解成一個(gè)容器【類(lèi)似于Map集合】
實(shí)現(xiàn)Servlet之間通訊就要用到ServletContext的setAttribute(String name,Object obj)方法,
第一個(gè)參數(shù)是關(guān)鍵字,第二個(gè)參數(shù)是你要存儲(chǔ)的對(duì)象
- 這是Demo2的代碼
- 這是Demo3的代碼
- 訪問(wèn)Demo3可以獲取Demo2存儲(chǔ)的信息,從而實(shí)現(xiàn)多個(gè)Servlet之間通訊
獲取web站點(diǎn)配置的信息
如果我想要讓所有的Servlet都能夠獲取到連接數(shù)據(jù)庫(kù)的信息,不可能在web.xml文件中每個(gè)Servlet中都配置一下,這樣代碼量太大了!并且會(huì)顯得非常啰嗦冗余。
- web.xml文件支持對(duì)整個(gè)站點(diǎn)進(jìn)行配置參數(shù)信息【所有Servlet都可以取到該參數(shù)信息】
- Demo4代碼
- 試一下Demo3是否能拿到,相同的代碼
讀取資源文件
第一種方式:
- 現(xiàn)在我要通過(guò)Servlet111讀取1.png圖片
- 按我們以前的方式,代碼應(yīng)該是這樣的。
- 當(dāng)我們?cè)L問(wèn)的時(shí)候,卻出錯(cuò)了!說(shuō)找不到1.png文件
- 這是為什么呢?我們以前讀取文件的時(shí)候,如果程序和文件在同一包名,可以直接通過(guò)文件名稱獲取得到的!,原因很簡(jiǎn)單,以前我們寫(xiě)的程序都是通過(guò)JVM來(lái)運(yùn)行的,而現(xiàn)在,我們是通過(guò)Tomcat來(lái)運(yùn)行的
- 根據(jù)web的目錄規(guī)范,Servlet編譯后的class文件是存放在WEB-INF\classes文件夾中的
- 看到這里,我們知道了要進(jìn)入classes目錄中讀取文件,所以我們將代碼改成以下方式
- 再去讀取時(shí),就發(fā)現(xiàn)可以獲取到文件了。
- 但是現(xiàn)在問(wèn)題又來(lái)了,我讀取文件的時(shí)候都要寫(xiě)上絕對(duì)路徑,這樣太不靈活了。試想一下,如果我將該讀取文件的模塊移到其他的web站點(diǎn)上,我的代碼就又要修改了【因?yàn)閣eb站點(diǎn)的名字不一樣】。
- 我們通過(guò)ServletContext讀取就可以避免修改代碼的情況,因?yàn)镾ervletContext對(duì)象是根據(jù)當(dāng)前web站點(diǎn)而生成的
- 代碼如下所示:
第二種方式:
- 如果我的文件放在web目錄下,那么就簡(jiǎn)單得多了!,直接通過(guò)文件名稱就能獲取
- 代碼如下所示
第三種方式:
通過(guò)類(lèi)裝載器讀取資源文件。
- 我的文件放在了src目錄下【也叫做類(lèi)目錄】
- 代碼如下所示
- 我的文件放在了src目錄下的包下
- 代碼如下,添加包名路徑即可。
原則:如果文件太大,就不能用類(lèi)裝載器的方式去讀取,會(huì)導(dǎo)致內(nèi)存溢出
轉(zhuǎn)載于:https://www.cnblogs.com/zhong-fucheng/p/7203059.html
總結(jié)
以上是生活随笔為你收集整理的Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: .ts 视频文件 .m3u8视频文件合并
- 下一篇: UWP_小说在线阅读器:功能要求与技术要