Struts(二)工作原理和具体流程

原理:

来自客户的所有请求,统一由Struts框架中的中心控制器ActionServlet接收,根据接收的请求参数和Struts配置(struts-config.XML)中ActionMapping,将请求送给合适的Action去处理,解决由谁做的问题,它们共同构成Struts的控制器。

Action则是Struts应用中真正干活的组件,它解决的是做什么的问题,它通过调用需要的业务组件来完成应用的业务,业务组件解决的是如何做的问题,并将执行的结果返回一个代表所需的描绘响应的JSP(或Action)的ActionForward对象给ActionServlet以将响应呈现给客户。

需要注意的是Action这个类,不应该包含过多的业务逻辑,而应该只是简单地收集业务方法所需要的数据并传递给业务对象。它的主要职责是:校验前提条件或者声明;调用需要的业务逻辑方法;检测或处理其他错误;路由控制到相关视图。真正的业务逻辑应该放到下一层的Model中处理。

原理示意图:

Struts(二)工作原理和具体流程

工作流程细节:

首先看web.xml中Struts的配置

<servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <!-- Standard Action Servlet Mapping --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> struts-config.xml中的配置: <struts-config> <form-beans> <form-bean name="loginForm" type="wh.LoginActionForm"></form-bean> </form-beans> <action-mappings> <action path="/login" type="wh.LoginAction" name="loginForm" scope="request" > <forward name="success" path="/success.jsp"></forward> <forward name="error" path="/error.jsp"></forward> </action> </action-mappings> </struts-config>


细节步骤:

(1)加载配置信息

Web容器(如Tomcat)启动时,通过web.xml的<struts>标签判断Struts的存在,web应用启动时就通过<strvlet-class>标签加载、初始化ActionServlet,struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时ActionServlet会读取配置文件struts-config.xml的配置信息,为struts中不同的模块初始化相应的对象。当ActionServlet接收到一个客户请求时,将执行如下流程:

(2)取得URL

Tomcat根据请求的路径格式判读是否使用Struts框架,本例中在web.xml中配置以do结尾则使用(如login.do以do结尾)。然后Tomcat通过<servlet-name>标签得到<servlet-class>的路径,调用ActionServlet的doGet()/doPost()方法,在doGet()/doPost()中调用process方法。

然后通过process调用到RequestProcessor类(这是一个核心控制类)中的processPath()方法来获取到请求的真正URL(例如login.do的到login)。如果不存在就返回请求路径无效信息;

(3)检索和用户请求匹配的ActionMapping,创建ActionForm

根据截取的URL调用processMapping(request, response, path)方法取得ActionMapping(根据struts-config.xml文件预先加载好的)。

然后根据得到的ActionMapping调用processActionForm(request, response, ActionMapping)方法,根据ActionMapping中name查找到ActionForm。

如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中。

然后通过调用processPopulate(request, response, form, mapping)方法将表单中的值设置到ActionForm对象中。

(4)验证表单

接着调用RequestProcessor类中的processValidate(request, response, form, mapping),看配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate(mapping, request)方法;

如果ActionForm的validate()方法返回null或返回一个不包含ActionMessage的ActuibErrors对象, 就表示表单验证成功;

(5)创建Action

接着调用RequestProcessor类中processActionCreate(request, response, mapping)方法,ActionServlet根据ActionMapping所包含的映射信息决定将请求转发给哪个Action,如果相应的Action实例不存在,就先创建这个实例。

(6)得到ActionForward,进行转向

接着调用RequestProcessor类中processActionPerform(request, response, action, form, mapping)执行查找到的用户自定义的Action中的execute()方法,Action一般只包含一个excute()方法,execute()方法返回一个ActionForward对象,ActionServlet在把客户请求转发给 ActionForward对象指向的JSP组件。

服务器通过ActionForward对象进行转发工作。ActionForward对象指向JSP组件生成动态网页,返回给客户。

最后附上具体流程的时序图。关于Struts的几个重要对象将在下次具体介绍。

Struts(二)工作原理和具体流程