Servlet
有以下四個階段:
1.加載和實例化
Servlet容器負責加載和實例化Servlet。
當Servlet容器啟動時,或者在容器檢測到需要這個Servlet來響應第一個請求時,創建Servlet實例。
當Servlet容器啟動后,它必須要知道所需的Servlet類在什么位置,Servlet容器可以從本地文件系統、遠程文件系統或者其他的網絡服務中通過類加載器加載Servlet類,
成功加載后,容器創建Servlet的實例。
因為容器是通過Java的反射API來創建 Servlet實例,調用的是Servlet的默認構造方法(即不帶參數的構造方法),所以我們在編寫Servlet類的時候,
不應該提供帶參數的構造方法。
2.初始化
在Servlet實例化之后,容器將調用Servlet的init()方法初始化這個對象。
初始化的目的是為了讓Servlet對象在處理客戶端請求前完成一些初始化的工作,如建立數據庫的連接,獲取配置信息等。
對於每一個Servlet實例,init()方法只被調用一次。在初始化期間,Servlet實例可以使用容器為它准備的ServletConfig對象從Web應用程序的配置信息(在web.xml中配置)
中獲取初始化的參數信息。
在初始化期間,如果發生錯誤,Servlet實例可以拋出ServletException異常或者UnavailableException異常來通知容器。
ServletException異常用於指明一般的初始化失敗,例如沒有找到初始化參數;
而UnavailableException異常 用於通知容器該Servlet實例不可用。
例如,數據庫服務器沒有啟動,數據庫連接無法建立,Servlet就可以拋出 UnavailableException異常向容器指出它暫時或永久不可用。
3.請求處理
Servlet容器調用Servlet的service()方法對請求進行處理。
要注意的是,在service()方法調用之前,init()方法必須成功執行。
在service()方法中,Servlet實例通過ServletRequest對象得到客戶端的相關信息和請求信息,在對請求進行處理后,調用ServletResponse對象的方法設置響應信息。
在service()方法執行期間,如果發生錯誤,Servlet實例可以拋出ServletException異常或者UnavailableException異常。
如果UnavailableException異常指示了該實例永久不可用,Servlet容器將調用實例的destroy()方法,釋放該實例。
此后對該實例的任何請求,都將收到容器發送的HTTP 404(請求的資源不可用)響應。如果UnavailableException異常指示了該實例暫時不可用,
那么在暫時不可用的時間段內,對該實例的任 何請求,都將收到容器發送的HTTP 503(服務器暫時忙,不能處理請求)響應。
4.服務終止
當容器檢測到一個Servlet實例應該從服務中被移除的時候,容器就會調用實例的destroy()方法,以便讓該實例可以釋放它所使用的資源,保存數據到持久存儲設備中。
當需要釋放內存或者容器關閉時,容器就會調用Servlet實例的destroy()方法。在destroy()方法調用之后,容器會釋放這個Servlet實例,
該實例隨后會被Java的垃圾收集器所回收。
如果再次需要這個Servlet處理請求,Servlet容器會創建一個新的Servlet實例。
也可以概括為:
Servlet程序是由WEB服務器調用,web服務器收到客戶端的Servlet訪問請求后:
①Web服務器首先檢查是否已經裝載並創建了該Servlet的實例對象。如果是,則直接執行第④步,否則,執行第②步。
②裝載並創建該Servlet的一個實例對象。
③調用Servlet實例對象的init()方法。
④創建一個用於封裝HTTP請求消息的HttpServletRequest對象和一個代表HTTP響應消息的HttpServletResponse對象,
然后調用Servlet的service()方法並將請求和響應對象作為參數傳遞進去。
⑤WEB應用程序被停止或重新啟動之前,Servlet引擎將卸載Servlet,並在卸載之前調用Servlet的destroy()方法。
*注意
在整個Servlet的生命周期過程中,創建Servlet實例、調用實例的init()和destroy()方法都只進行一次,
當初始化完成后,Servlet容器會將該實例保存在內存中,通過調用它的service()方法,為接收到的請求服務。
Struts2
1.流程圖:
2.流程敘述:
1. 客戶端發送請求; 2. 這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對於Struts2和其他框架的集成很有幫助,
例如:SiteMesh Plugin) 3. 接着FilterDispatcher被調用,FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action。FilterDispatcher的功能如下: (1)執行Actions (2)清除ActionContext (3)維護靜態內容 (4)清除request生命周期內的XWork的interceptors 4. 如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy 5. ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類 6. ActionProxy創建一個ActionInvocation的實例。 7. ActionInvocation實例使用命名模式來調用,在調用Action的過程前后,涉及到相關攔截器(Intercepter)的調用。 8. 一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。
返回結果通常是(但不總是,也可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。
在表示的過程中可以使用Struts2框架中繼承的標簽。在這個過程中需要涉及到ActionMapper
詳情鏈接:struts2執行原理(執行流程)
SpringMVC
1.流程圖:
2.流程描述:
1. 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲; 2. DispatcherServlet對請求URL進行解析,得到請求資源標識符(URI)。然后根據該URI,調用HandlerMapping獲得該Handler配置的所有相關的對象
(包括Handler對象以及Handler對象對應的攔截器),最后以HandlerExecutionChain對象的形式返回。 3. DispatcherServlet 根據獲得的Handler,選擇一個合適的HandlerAdapter。(附注:如果成功獲得HandlerAdapter后,此時將開始執行攔截器的preHandler(...)方法) 4. 提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。
在填充Handler的入參過程中,根據你的配置,Spring將幫你做一些額外的工作: 1)HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換為指定的響應信息 2)數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等 3)數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等 4)數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中 5. Handler執行完成后,向DispatcherServlet 返回一個ModelAndView對象; 6. 根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經注冊到Spring容器中的ViewResolver)返回給DispatcherServlet ; 7. ViewResolver 結合Model和View,來渲染視圖 8. 將渲染結果返回給客戶端。
也可以說:
處理流程規范化的首要內容就是考慮一個通用的Servlet響應程序大致應該包含的邏輯步驟:
步驟1—— 對Http請求進行初步處理,查找與之對應的Controller處理類(方法) ——HandlerMapping
步驟2—— 調用相應的Controller處理類(方法)完成業務邏輯 ——HandlerAdapter
步驟3—— 對Controller處理類(方法)調用時可能發生的異常進行處理 ——HandlerExceptionResolver
步驟4—— 根據Controller處理類(方法)的調用結果,進行Http響應處理 ——ViewResolver
Struts2與SpringMVC的對比
文章鏈接: SpringMVC與Struts2的對比