ActionServlet類是Struts框架的內置核心控制器組件,它繼承了javax.servlet.http.HttpServlet類。Struts的啓動一般從html
加載ActionServlet開始。Web容器會在首次啓動或Struts應用的第一個請求到達時加載ActionServlet。通常狀況下都java
配置web容器好比tomcat啓動的時候加載ActionServlet類,使用<load-on-startup>1</load-on-startup>標籤配置啓動web
加載。瀏覽器
ActionServlet有以下這幾個功能tomcat
ActionServlet加載的時候讀取Struts-config.xml文件,將文件對應的配置信息讀取到內存中,ActionServlet 根據不一樣的模塊來初始化 ModuleConfig 類,並在其中以XXXconfig 集合的方式保存該模塊的各類配置信息,好比 ActionConfig,FormBeanConfig 等。app
好比配置文件中的 Action映射定義都保存在 ActionConfig 集合中。相應地有 ControlConfig 集合、FormBeanConfig 集合、ForwardConfig集合和 MessageResourcesConfig 集合等。框架
這裏的模塊是爲了用於不一樣用戶在同時使用struts-config.xml文件時衝突,每一個用戶能夠定義本身的配置文件,由容器自動去整合配置,每一個配置文件至關於一個模塊。ui
初始化工做完成以後,ActionServlet準備接收客戶請求。針對每一個請求,方法 process(HttpServletRequest request, HttpServletResponseresponse) 將被調用。該方法指定具體的模塊,而後調用該模塊的 RequestProcessor 的 process 方法。spa
其實根據Servlet的原理,應該調用ActionServlet的doPost()或doGet()方法來處理用戶請求,而它們實際上都是調用process()方法具體處理請求的,以下列代碼:debug
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { process(request, response); }
public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { process(request, response); }
protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { //根據請求選擇適當的應用模塊 ModuleUtils.getInstance().selectModule(request, getServletContext()); ModuleConfig config = getModuleConfig(request); //獲取模塊相關的RequestProcesser實例 RequestProcessor processor = getProcessorForModule(config); if (processor == null) { processor = getRequestProcessor(config); } //調用processor實例的process()方法處理請求 processor.process(request, response); }
在上面咱們看到ActionServlet的process()方法中實際處理用戶請求的是RequestProcessor類的process()方法。Struts框架只容許應用程序中存在一個ActionServlet類,但每一個應用程序模塊都有各自的RequestProcessor類實例。在ActionServlet的process()方法中,一旦選擇了正確的應用程序模塊,就會調用相應模塊RequestProcessor實例的process()方法來處理請求。RequestProcessor類的process方法以下:
//摘自RequestProcessor public void process(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException { //用一個特殊的包裝對象把Muiltipart請求包裝起來 request = processMultipart(request); //驗證咱們用來選擇映射的路徑組件 String path = processPath(request, response); if (path != null) { if (log.isDebugEnabled()) log.debug("Processing a '" + request.getMethod() + "' for path '" + path + "'"); //有請求時, 爲當前用戶選擇一個Locale對象 processLocale(request, response); //有請求時,設置內容類型和no-caching字頭 processContent(request, response); processNoCache(request, response); if (processPreprocess(request, response)) { processCachedMessages(request, response); //驗證這個請求的映射 ActionMapping mapping = processMapping(request, response, path); if (mapping != null && processRoles(request, response, mapping)) { //處理和這個請求相關的任何ActionForm bean ActionForm form = processActionForm(request, response, mapping); processPopulate(request, response, form, mapping); if (processValidate(request, response, form, mapping)&& processForward(request, response, mapping)&& processInclude(request, response, mapping)) { //建立或獲取Action實例來處理這項請求 Action action = processActionCreate(request, response, mapping); if (action != null) { //調用Action實例自己 ActionForward forward = processActionPerform(request, response,action, form, mapping); //處理所返回的ActionForward實例 processForwardConfig(request, response, forward); } } } } } }
ActionServlet在 ActionConfig 中找出對應於該請求的 Action 子類,若是沒有對應的 Action,控制器直接將請求轉發給 JSP或者靜態頁面。不然控制器將請求分發至具體 Action 類進行處理。
在控制器調用具體 Action 的 execute方法以前,ActionForm 對象將利用 HTTP 請求中的參數來填充本身(可選步驟,須要在配置文件中指定)。具體的 ActionForm 對象應該是ActionForm 的子類對象,它其實就是一個 JavaBean。
須要特別說明的是,Struts的配置文件struts-config.xml做爲ActionServlet的一個初始化參數值在web.xml文件中聲明。另外,ActionServlet的URL形式是*.do,這樣當在瀏覽器地址輸入任何後綴爲*.do的URL時,系統都會映射到ActionServlet。