Struts的工作流程
***装载并实例化ActionServlet***
当Web Server启动装载Web应用(基于Struts)时,容器先将ActionServlet装载进虚拟机并实例化,接着调用init()方法,在init()中
ActionServlet去解析struts-config.xml文件,将其中的元素信息封装到相应的对象中,对象被存放到Struts框架维护的集合中。
例如:
<form-bean>元素 --> ActionFormBean对象
<action>元素 --> ActionMapping对象
元素中的属性 --> 对象中的属性
注: ActionFormBean和ActionMapping对象被存放在Struts框架维护的HashMap中
HashMap formbeans(name,ActionFormBean对象引用)
HashMap actionconfigs(path,ActionMapping对象引用)
init()方法调用完毕后,ActionServlet处于service状态,可以接受客户端的请求。
(1) 接受客户端所有*.do请求
当客户端发出请求的URL以*.do结尾,那么这些请求将被ActionServlet接受。
(2) 调用RequestProcessor的process()方法
ActionServlet接受到*.do请求后,首先构造一个RequestProcessor对象(单例),然后调
用其process(request,response)方法,将请求委托给RequestProcessor来处理。
(3) 查找请求所对应的ActionMapping对象(定位自定义的Action)
RequestProcessor将请求URL中的servletPath(如:/basic/register.do)截取.do后变成
/basic/register(path),然后根据这个path到HashMap中查找对应的ActionMapping对象,若没有找到,返回404错误代 码到客户端,若找到也就能获得属性type指定的Action。
(4) 查找或者构造ActionForm对象
根据<action>元素中属性scope指定的范围去查找是否存在配置的ActionForm对象,
(例如:request.getAttribute(key)),key就是属性attribute指定的值。若找到该对象,
就不会去构造一个新的ActionForm对象,若没有找到,先构造一个新的ActionForm对
象,然后将该对象放置到scope指定的范围中(request.setAttribute(key,ActionForm对象引用))。
注意: 若Action没有配置ActionForm,那么(4)~(7)就不执行。
判断是否配置ActionForm的方式:
根据<action>元素中属性name的值(如:registerForm)去HashMap中查找对应的
ActionFormBean对象,找到该对象也就找到了属性type指定的ActionForm。
(5) 调用ActionForm的reset()方法
调用此方法进行属性的初始化(基本数据类型设置为0,布尔型设置为false,String设
置为null)。
注意: 此方法要用户自己去实现,但是若ActionForm对象存放在request中可以
不实现该方法,若存放在session中最好实现该方法,对所有的属性进行初始化。
(6) 调用ActionForm的setXXX()方法
调用此方法就将提交表单中的字段信息封装到ActionForm的属性中。
(7) 调用ActionForm的validate()方法(可选)
如果<action>元素中的属性validate为true,那么就调用validate()方法进行表单字段的
验证,该方法由用户提供实现。若设置false就不调用该方法。
注意: 该方法并返回一个ActionErrors对象(内置一个集合),若集合中含有
ActionMessage对象(封装错误消息),验证就不通过,接着跳转到属性input指定的jsp。若返
回null或者ActionErrors对象内置的集合中不含有ActionMessage对象,验证就通过。
(8) 查找或者构造Action对象(单例)
RequestProcessor首先判断在放置Action缓存(HashMap)中是否已经存在一个Action对
象,若没有就构造一个新的Action对象,并放置到Action缓存中。
注意: Action缓存是一个HashMap,存放形式:
(className,Action对象引用),className就是<action>元素中属性type指定的值。
(9) 调用Action的execute()方法
此方法类似Servlet中的service方法,返回结果为一个ActionForward对象.xuxiang5612@sina.com
(9-1) 调用ActionForm的getXXX()方法
在Action的execute()中可以先调用ActionForm的getXXX()方法来获得所有封
装在ActionForm中的表单字段信息。
注意: 提交表单中的字段信息还可以通过request.getParameter(name)来获得
(9-2) 调用模型层中的service()方法(业务接口方法)
在Action的execute()中调用模型层中的业务接口方法,处理业务逻辑。
(9-3) 调用ActionMapping的findForward()方法
在Action的execute()中最后调用此方法返回一个ActionForward对象。
(10) 调用ActionForward的getPath()
调用此方法返回一个ActionForward对象中封装的服务器端资源的path(Jsp、Servlet或
者Action)。
(11) 进行跳转或者重定向
RequestProcessor根据ActionForward封装的path和redirect的值进行跳转或者重定向
到另外一个服务器端的资源(Jsp、Servlet或者Action)。
(12) 返回一个response到客户端
动态生成一个html加入到response中并返回到客户端,由浏览器解析显示。