Servlet的理解和認識2

Servlet規範簡介——web框架是如何注入到Servlet中的

引言

Web框架通常是經過一個Servlet提供統一的請求入口,將指定的資源映射到這個servlet,在這個servlet中進行框架的初始化配置,訪問Web頁面中的數據,進行邏輯處理後,將結果數據與的表現層相融合並展示給用戶。WEB框架想要在符合Servlet規範的容器中運行,一樣也要符合Servlet規範。html

將一個WEB框架注入到一個servlet中,主要涉及到Servlet規範中如下部分:java

Ø         部署描述符web

Ø         映射請求到Servlet安全

Ø         Servlet生存週期服務器

Ø         請求分發app

 Servlet相關技術規範簡介

部署描述符

部署描述符就是位於WEB應用程序的/WEB-INF目錄下的web.xml的XML文件,是WEB應用程序不可分割的部分,管理着WEB應用程序的配置。部署描述符在應用程序開發人員,應用程序組裝人員,應用程序部署人員之間傳遞WEB應用程序的元素和配置信息。框架

在WEB應用程序的部署描描述符中如下類型的配置和部署信息是全部的servlet容器必須支持的:jsp

Ø         ServletContext初始化參數url

Ø         Session配置spa

Ø        Servlet聲明

Ø        Servlet映射

Ø        應用程序生存週期監聽器

Ø         Filter的定義和映射

Ø         MIME類型的映射

Ø        歡迎文件列表

Ø        錯誤文件列表

出如今部署描述符中的安全信息能夠不被支持,除非這個Servlet容器是J2EE規範實現的一部分。

全部正確的WEB應用程序部署描述符(Servlet2.3規範)必須包含下面的DOCTYPE聲明:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web

Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

 

下面說明在部署描述符中是如何進行Servlet聲明和映射的,這個DTD的所有內容能夠在下面這個地址得到:

http://java.sun.com/dtd/web-app_2_3.dtd

在這個DTD中有關Servlet聲明和映射和映射的部分以下:

<!--

The servlet element contains the declarative data of a

servlet. If a jsp-file is specified and the load-on-startup element

is present, then the JSP should be precompiled and loaded.

Used in: web-app

-->

<!ELEMENT servlet (icon?, servlet-name, display-name?, description?,

(servlet-class|jsp-file), init-param*, load-on-startup?, runas?,

security-role-ref*)>

<!--

The servlet-class element contains the fully qualified class name

of the servlet.

Used in: servlet

-->

<!ELEMENT servlet-class (#PCDATA)>

<!--

The servlet-mapping element defines a mapping between a servlet

and a url pattern

Used in: web-app

-->

<!ELEMENT servlet-mapping (servlet-name, url-pattern)>

<!--

The servlet-name element contains the canonical name of the

servlet. Each servlet name is unique within the web application.

Used in: filter-mapping, servlet, servlet-mapping

-->

<!ELEMENT servlet-name (#PCDATA)>

根據以上DTD,一個典型的Servlet的聲明的格式以下:

<servlet>

<servlet-name>catalog</servlet-name>

<servlet-class>com.mycorp.CatalogServlet</servlet-class>

<init-param>

<param-name>catalog</param-name>

<param-value>Spring</param-value>

</init-param>

</servlet>

一個典型的Servlet映射以下:

<servlet-mapping>

<servlet-name>catalog</servlet-name>

<url-pattern>/catalog/*</url-pattern>

</servlet-mapping>

 

經過上面的方法,咱們就聲明瞭一個名稱爲catalog的Servlet,它的實現類爲com.mycorp.CatalogServlet,而且帶有一個catalog參數,參數值爲Spring,全部向/catalog/*的請求都被映射到名稱爲catalog的Servlet。

 

映射請求到Servlet

接收到一個請求後,WEB容器要肯定轉到哪個WEB應用程序。被選擇的應用程序的最長的上下文路徑必須和請求的URL開始部分匹配。URL匹配的部分是映射到Servlet的上下文路徑。

WEB容器下一步必須按照下面的程序定位處理請求的Servlet。

用來映射到Servlet的路徑是請求對象的URL減去上下文的路徑。下面的URL路徑映射規則按順序執行,容器選擇第一個成功的匹配而且不在進行下一個匹配:

Ø        容器試着對請求的路徑和Servlet的路徑進行精確匹配,若是匹配成功則選擇這個Servlet。

Ø        容器會循環的去試着匹配最長的路徑前綴:把’/’看成路徑分隔符,按照路徑樹逐級遞減的完成,選擇最長匹配的Servlet。

Ø        若是這個URL路徑的最後有擴展名(好比.jsp),Servlet容器會試着匹配處理這個擴展名的Servlet。

Ø        若是前面的沒有與前面三條規則相匹配的Servlet,容器會試着爲資源請求提供適當的資源,若是有「默認」的Servlet定義給這個應用程序,那麼這個Servlet會被使用。

 

容器必須使用一個大小寫敏感的匹配方式。

在部署描述符中,用下面的語法定義映射:

Ø        一個以’/’開始而且以’/*’結束的字符串用來映射路徑。

Ø        一個以’*.’爲前綴的字符串用來映射擴展名。

Ø        一個只包含’/’的字符串指示着這個應用程序「默認」的Servlet,在這種狀況下,servlet的路徑是請求的URI減去上下文路徑,而且這個路徑是null。

Ø        全部其餘的字符只用來精確匹配。

若是容器內置JSP容器,那麼*.jsp被映射到這個容器,並容許JSP頁面在須要的時候被執行。這種映射叫作隱含映射。若是WEB應用程序中定義了*.jsp的映射,那麼這個映射有比隱含映射高的優先級。

WEB容器容許顯式的聲明隱含映射以得到優先級,例如,*.shtml的隱含映射能夠在服務器上被映射爲包含功能。

映射實例:

path pattern

servlet

/foo/bar/*

servlet1

/baz/*

servlet2

/catalog

servlet3

*.bop

servlet4

下面是實際請求映射的結果

incoming path

servlet handling request

/foo/bar/index.html

servlet1

/foo/bar/index.bop

servlet1

/baz

servlet2

/baz/index.html

servlet2

/catalog

servlet3

/catalog/index.html

「default」 servlet

/catalog/racecar.bop

servlet4

/index.bop

servlet4

請注意/catalog/index.html 和/catalog/racecar.bop這兩種狀況,由於是精確匹配,因此並無映射處處理/catalog的servlet。

 

Servlet生存週期

在介紹Servlet的生存週期以前須要先介紹一下javax.servlet.Servlet接口。全部的Servlet必須實現或者間接實現這個藉口,咱們一般能夠經過繼承javax.servlet.GenericServlet或者javax.servlet.http.HttpServlet.類來實現這個接口。

這個接口中定義了下面5種方法:

public void init(ServletConfig config);

public ServletConfig getServletConfig();

public void service(ServletRequest req, ServletResponse res);

public String getServletInfo();

public void destroy() ;

 

init()方法

init方法在容器器裝入Servlet 時執行,Servlet容器在實例化後只調用一次init方法, init方法必須在servlet接收到任何請求以前完成。

這個方法一般用來進行一些資源的管理和初始化,如從配置文件讀取配置數據,讀取初始化參數,初始化緩衝遲等一次性的操做。

getServletConfig()方法

GetServletConfig方法返回一個 ServletConfig 對象,該對象用來返回這個Servlet的初始化信息和啓動參數。返回的是傳遞到init方法ServletConfig。

Service()方法

Service方法是應用程序邏輯的進入點,是servlet方法的核心,WEB容器調用這個方法來響應進入的請求,只有servlet成功被init()方法初始化後,Service方法纔會被調用。

getServletInfo()方法

這個方法返回一個字符串對象,提供有關servlet 的信息,如做者、版本等。

destroy()方法

destroy方法在容器移除Servlet 時執行,一樣只執行一次。這個方法會在全部的線程的service()方法執行完成或者超時後執行,調用這個方法後,容器不會再調用這個servlet的方法,也就是說容器再也不把請求發送給這個Servlet。 這個方法給servlet釋放佔用的資源的機會,一般用來執行一些清理任務。

 

這個接口定義了初始化一個servlet,服務請求和從容器中移除servlet的方法。他們按照下面的順序執行:

1.         servlet被實例化後,用init方法進行初始化

2.         客戶端的任何請求都調用service方法

3.         servlet被移除服務,調用destroy方法銷燬

servlet的生存週期以下圖:
 

請求分發

請求分發可讓一個Servlet把請求分配到另一個資源,RequestDispatcher接口提供了實現他的機制。能夠經過下面兩種方式從ServletContext中得到一個實現了RequestDispatcher接口的對象:

• getRequestDispatcher

• getNamedDispatcher

getRequestDispatcher方法接受一個指向目標資源的URL路徑

RequestDispatcher rd = getServletContext().getRequestDispatcher(「/catalog」);

 

 

getNamedDispatcher方法接受一個Servlet名稱參數,這個名稱是在部署描述符中<servlet-name>元素指定的那個名稱。

RequestDispatcher rd = getServletContext().getNamedDispatcher (「catalog」);

 

 

RequestDispatcher接口有兩個方法,容許你在調用的servlet完成初步處理後把請求響應分配到另一個資源,

forward()方法:

public void forward(ServletRequest request, ServletReponse reponse) throws SwerletException,IOException

forward方法上讓你把請求轉發到另外的Servlet或者jsp或者html等資源,由這個資源接下來負責響應。如:

RequestDispatcher rd = getServletContext().getRequestDispatcher(「/catalog」);

rd. forward(request,response);

 

include()方法:

public void include (ServletRequest request, ServletReponse reponse) throws SwerletException,IOException

include方法讓你的Servlet響應中包含另一個資源生成內容

RequestDispatcher rd = getServletContext().getRequestDispatcher(「/catalog」);

rd. include(request,response);

 

 

結合WebWork的具體分析

WebWork是由OpenSymphony組織開發實現MVC模式的J2EE Web框架。在介紹完servlet規範的相關內容後,咱們看看WebWork是如何注入到一個Servlet中的,假設咱們有一個上下文環境爲「/WebWorkdDemo」的WEB應用。

部署描述符

在部署描述符中,咱們須要進行以下配置:

<servlet>

<servlet-name>webwork</servlet-name>

<servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class>

</servlet>

……

<servlet-mapping>

<servlet-name>webwork</servlet-name>

<url-pattern>*.action</url-pattern>

</servlet-mapping>

咱們聲明瞭一個名爲webwork的Servlet和*.action到這個Servlet的映射,這個Servlet就是webwork中的controller,擔任MVC框架中很是重要的控制器角色。

映射請求到Servlet

在XWork的配置文件xwork.xml中有以下片斷:

<action name="demo" class=" webworkapp.DemoAction">

<result name="success" type="dispatcher">

<param name="location">/demo.jsp</param>

</result>

</action>

這樣咱們由http://localhost:8080/WebWorkDemo/demo.action這個URL向服務器發出請求時,WEB容器首先肯定轉到哪個WEB應用程序,容器將請求URL和上下文環境進行匹配後知道將轉到/WebWorkdDemo這個WEB應用。

接下來容器會在/WebWorkdDemo這個應用的部署描述符中進行查找處理這個請求的servlet,根據後綴*.action找到名稱爲webwork這個Servlet,這樣根據部署描述符,這個請求被映射到webwork中的controller組 .

轉自: https://www.cnblogs.com/BigTailWolf/p/6241070.html

相關文章
相關標籤/搜索