Servlet应用之细节
?由于客戶端是通過(guò)URL地址訪問(wèn)web服務(wù)器中的資源,所以Servlet程序若想被外界訪問(wèn),必須把servlet程序映射到一個(gè)URL地址上,這個(gè)工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。
<servlet>元素用于注冊(cè)Servlet,它包含有兩個(gè)主要的子元素:<servlet-name>和<servlet-class>,分別用于設(shè)置Servlet的注冊(cè)名稱和Servlet的完整類名。
一個(gè)<servlet-mapping>元素用于映射一個(gè)已注冊(cè)的Servlet的一個(gè)對(duì)外訪問(wèn)路徑,它包含有兩個(gè)子元素:<servlet-name>和<url-pattern>,分別用于指定Servlet的注冊(cè)名稱和Servlet的對(duì)外訪問(wèn)路徑。例如:
<web-app>
<servlet>
<servlet-name>AnyName</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AnyName</servlet-name>
<url-pattern>/demo/hello.html</url-pattern>
</servlet-mapping>
</web-app>
同一個(gè)Servlet可以被映射到多個(gè)URL上,即多個(gè)<servlet-mapping>元素的<servlet-name>子元素的設(shè)置值可以是同一個(gè)Servlet的注冊(cè)名。
在Servlet映射到的URL中也可以使用*通配符,但是只能有兩種固定的格式:一種格式是“*.擴(kuò)展名”,另一種格式是以正斜杠(/)開頭并以“/*”結(jié)尾。
<servlet-mapping>
<servlet-name>
AnyName
</servlet-name>
<url-pattern>
*.do
</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>
AnyName
</servlet-name>
<url-pattern>
/action/*
</url-pattern>
</servlet-mapping>
?
對(duì)于如下的一些映射關(guān)系:
Servlet1 映射到 /abc/*
Servlet2 映射到 /*
Servlet3 映射到 /abc
Servlet4 映射到 *.do
問(wèn)題:
當(dāng)請(qǐng)求URL為“/abc/a.html”,“/abc/*”和“/*”都匹配,哪個(gè)servlet響應(yīng)
Servlet引擎將調(diào)用Servlet1。
當(dāng)請(qǐng)求URL為“/abc”時(shí),“/abc/*”和“/abc”都匹配,哪個(gè)servlet響應(yīng)
Servlet引擎將調(diào)用Servlet3。
當(dāng)請(qǐng)求URL為“/abc/a.do”時(shí),“/abc/*”和“*.do”都匹配,哪個(gè)servlet響應(yīng)
Servlet引擎將調(diào)用Servlet1。
當(dāng)請(qǐng)求URL為“/a.do”時(shí),“/*”和“*.do”都匹配,哪個(gè)servlet響應(yīng)
Servlet引擎將調(diào)用Servlet2。
當(dāng)請(qǐng)求URL為“/xxx/yyy/a.do”時(shí),“/*”和“*.do”都匹配,哪個(gè)servlet響應(yīng)
Servlet引擎將調(diào)用Servlet2。
?
Servlet是一個(gè)供其他Java程序(Servlet引擎)調(diào)用的Java類,它不能獨(dú)立運(yùn)行,它的運(yùn)行完全由Servlet引擎來(lái)控制和調(diào)度。
?
針對(duì)客戶端的多次Servlet請(qǐng)求,通常情況下,服務(wù)器只會(huì)創(chuàng)建一個(gè)Servlet實(shí)例對(duì)象,也就是說(shuō)Servlet實(shí)例對(duì)象一旦創(chuàng)建,它就會(huì)駐留在內(nèi)存中,為后續(xù)的其它請(qǐng)求服務(wù),直至web容器退出,servlet實(shí)例對(duì)象才會(huì)銷毀。
?
在Servlet的整個(gè)生命周期內(nèi),Servlet的init方法只被調(diào)用一次。而對(duì)一個(gè)Servlet的每次訪問(wèn)請(qǐng)求都導(dǎo)致Servlet引擎調(diào)用一次servlet的service方法。對(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方法。
?
如果在<servlet>元素中配置了一個(gè)<load-on-startup>元素,那么WEB應(yīng)用程序在啟動(dòng)時(shí),就會(huì)裝載并創(chuàng)建Servlet的實(shí)例對(duì)象、以及調(diào)用Servlet實(shí)例對(duì)象的init()方法。
舉例:
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
?
用途:為web應(yīng)用寫一個(gè)InitServlet,這個(gè)servlet配置為啟動(dòng)時(shí)裝載,為整個(gè)web應(yīng)用創(chuàng)建必要的數(shù)據(jù)庫(kù)表和數(shù)據(jù)。
?
如果某個(gè)Servlet的映射路徑僅僅為一個(gè)正斜杠(/),那么這個(gè)Servlet就成為當(dāng)前Web應(yīng)用程序的缺省Servlet。
凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它們的訪問(wèn)請(qǐng)求都將交給缺省Servlet處理,也就是說(shuō),缺省Servlet用于處理所有其他Servlet都不處理的訪問(wèn)請(qǐng)求。
在<tomcat的安裝目錄>\conf\web.xml文件中,注冊(cè)了一個(gè)名稱為org.apache.catalina.servlets.DefaultServlet的Servlet,并將這個(gè)Servlet設(shè)置為了缺省Servlet。
當(dāng)訪問(wèn)Tomcat服務(wù)器中的某個(gè)靜態(tài)HTML文件和圖片時(shí),實(shí)際上是在訪問(wèn)這個(gè)缺省Servlet。
?
線程安全
當(dāng)多個(gè)客戶端并發(fā)訪問(wèn)同一個(gè)Servlet時(shí),web服務(wù)器會(huì)為每一個(gè)客戶端的訪問(wèn)請(qǐng)求創(chuàng)建一個(gè)線程,并在這個(gè)線程上調(diào)用Servlet的service方法,因此service方法內(nèi)如果訪問(wèn)了同一個(gè)資源的話,就有可能引發(fā)線程安全問(wèn)題。
如果某個(gè)Servlet實(shí)現(xiàn)了SingleThreadModel接口,那么Servlet引擎將以單線程模式來(lái)調(diào)用其service方法。
SingleThreadModel接口中沒(méi)有定義任何方法,只要在Servlet類的定義中增加實(shí)現(xiàn)SingleThreadModel接口的聲明即可。
對(duì)于實(shí)現(xiàn)了SingleThreadModel接口的Servlet,Servlet引擎仍然支持對(duì)該Servlet的多線程并發(fā)訪問(wèn),其采用的方式是產(chǎn)生多個(gè)Servlet實(shí)例對(duì)象,并發(fā)的每個(gè)線程分別調(diào)用一個(gè)獨(dú)立的Servlet實(shí)例對(duì)象。
實(shí)現(xiàn)SingleThreadModel接口并不能真正解決Servlet的線程安全問(wèn)題,因?yàn)?/font>Servlet引擎會(huì)創(chuàng)建多個(gè)Servlet實(shí)例對(duì)象,而真正意義上解決多線程安全問(wèn)題是指一個(gè)Servlet實(shí)例對(duì)象被多個(gè)線程同時(shí)調(diào)用的問(wèn)題。事實(shí)上,在Servlet API 2.4中,已經(jīng)將SingleThreadModel標(biāo)記為Deprecated(過(guò)時(shí)的)
?
ServletConfig對(duì)象
在Servlet的配置文件中,可以使用一個(gè)或多個(gè)<init-param>標(biāo)簽為servlet配置一些初始化參數(shù)。
?
當(dāng)servlet配置了初始化參數(shù)后,web容器在創(chuàng)建servlet實(shí)例對(duì)象時(shí),會(huì)自動(dòng)將這些初始化參數(shù)封裝到ServletConfig對(duì)象中,并在調(diào)用servlet的init方法時(shí),將ServletConfig對(duì)象傳遞給servlet。進(jìn)而,程序員通過(guò)ServletConfig對(duì)象就可以得到當(dāng)前servlet的初始化參數(shù)信息。
?
閱讀ServletConfig API,并舉例說(shuō)明該對(duì)象的作用:
獲得字符集編碼
獲得數(shù)據(jù)庫(kù)連接信息
獲得配置文件
?
ServletContext
WEB容器在啟動(dòng)時(shí),它會(huì)為每個(gè)WEB應(yīng)用程序都創(chuàng)建一個(gè)對(duì)應(yīng)的ServletContext對(duì)象,它代表當(dāng)前web應(yīng)用。
ServletConfig對(duì)象中維護(hù)了ServletContext對(duì)象的引用,開發(fā)人員在編寫servlet時(shí),可以通過(guò)ServletConfig.getServletContext方法獲得ServletContext對(duì)象。
也可以使用 this.getServletContext方法
由于一個(gè)WEB應(yīng)用中的所有Servlet共享同一個(gè)ServletContext對(duì)象,因此Servlet對(duì)象之間可以通過(guò)ServletContext對(duì)象來(lái)實(shí)現(xiàn)通訊。多個(gè)Servlet通過(guò)ServletContext對(duì)象實(shí)現(xiàn)數(shù)據(jù)共享。
ServletContext對(duì)象通常也被稱之為context域?qū)ο蟆?#xff08;request,session,page)
setAttribute(),getAttribute();
?
ServletContext應(yīng)用
獲取WEB應(yīng)用的初始化參數(shù)。
<context-param>
<param-name> data</param-name>
<param-value> xxxx</param-value>
</context-param>
?
實(shí)現(xiàn)Servlet的轉(zhuǎn)發(fā)。
RequestDispatcher rd = getServletContext().getRequestDispatcher(“/1.jsp”);
rd.forward(request,response);
如何把數(shù)據(jù)傳到 1.jsp ?(可以通過(guò)request域,不能用context域)
?
ServletConfig和ServletContext的區(qū)別
整個(gè)Web應(yīng)用只有一個(gè)ServletContext,在部署Web應(yīng)用的時(shí)候,容器會(huì)建立這一個(gè)ServletContext對(duì)象,這個(gè)上下文對(duì)Web應(yīng)用中的每個(gè)Servlet和JSP都可用。
Web應(yīng)用中的各個(gè)Servlet都有自己的ServletConfig,它只對(duì)當(dāng)前Servlet有效。
?
在客戶端緩存Servlet的輸出
對(duì)于不經(jīng)常變化的數(shù)據(jù),在servlet中可以為其設(shè)置合理的緩存時(shí)間值,以避免瀏覽器頻繁向服務(wù)器發(fā)送請(qǐng)求,提升服務(wù)器的性能。
?
?
?
?
?
?
轉(zhuǎn)載于:https://blog.51cto.com/fighter2013/1147895
總結(jié)
以上是生活随笔為你收集整理的Servlet应用之细节的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: chrome下的img.onload
- 下一篇: mybatis的环境搭建及如何和搭配sp