Web框架通常是經過一個Servlet提供統一的請求入口,將指定的資源映射到這個servlet,在這個servlet中進行框架的初始化配置,訪問Web頁面中的數據,進行邏輯處理後,將結果數據與的表現層相融合並展示給用戶。WEB框架想要在符合Servlet規範的容器中運行,一樣也要符合Servlet規範。html
將一個WEB框架注入到一個servlet中,主要涉及到Servlet規範中如下部分:java
Ø 部署描述符web
Ø 映射請求到Servlet安全
Ø Servlet生存週期服務器
Ø 請求分發app
部署描述符就是位於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。
接收到一個請求後,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的生存週期以前須要先介紹一下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是由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框架中很是重要的控制器角色。
在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