struts处理请求全过程
在用Struts开发的Web应用中,我们主要编写Action类来处理到来的请求,但请求到达Action之前,Struts为我们做了很多工作。
Struts使用ActionServlet统一处理所有到来的请求,每到来一个请求,它都要做很多事情,执行我们编写的Action只是其中之一,Struts处理请求的过程如下:
?
1. 选择模块
根据请求URL和应用的所有模块名(这个模块名的集合在ActionServlet的初始化时放到ServletContext里),分析出请求对应的模块名。
根据这个模块名,从ServletContext里拿到对应的模块(ModuleConfig对象),放到request作用域里。
根据这个模块里的MessageResources配置信息,从ServletContext里拿到对应的MessageResources对象,放到request作用域里。
?
2. 获得模块对应的RequestProcessor
从ServletContext里拿模块对应的RequestProcessor,如果没拿到(说明模块第一次被访问),根据模块里Controller的配置信息创建一个RequestProcessor,放到ServletContext里。
?
3. 处理multipart请求
如果请求是POST的,并且其contentType属性值为multipart/form-data,将请求包装成MultipartRequestWrapper。
?
4. 处理请求路径
将请求的URI掐头去尾,也就是将URI中的模块名和后缀名两部分去掉。如果路径为null,处理请求结束。
?
5. 处理Locale
如果Struts配置文件里controller元素的locale属性没有指定为false(默认为true),并且session里没有Locale的话,就从request里拿到Locale,放到session里。
?
6. 处理内容类型
获得Struts配置文件里controller元素的contentType属性值(默认为text/html),将response的内容类型设置为该值。
?
7. 处理no-cache headers
如果Struts配置文件里controller元素的nocache属性指定为true(默认为false),设置response的相关header属性。
?
8. 预处理
默认的,Struts在这一步没做任何事情,如果需要,可以继承RequestProcessor,重写这一步,实现条件性的确定是否继续执行后面的步骤。
?
9. 处理缓存信息
在session里找名字为Globals.MESSAGE_KEY和Globals.ERROR_KEY的ActionMessages,如果有并且已经被访问过,就从session里删除它们。
?
10. 处理ActionMapping
根据请求的路径,从模块里找ActionMapping(对应于Struts配置文件里的action元素),如果没有完全匹配路径的,就找模糊匹配的。
如果没找到,就找第一个指定unknown属性为true的。
找到后放到request里,没找到就向response发送错误信息。
?
11. 处理角色权限
针对上面拿到的ActionMapping,如果它设置了roles属性值,检查请求者是否属于这些角色。
?
12. 处理ActionForm
针对上面拿到的ActionMapping,根据它的name属性,查找对应的form-bean元素。
根据它的attribute和scope属性,在request或session里查找ActionForm,如果找到,还要对照刚才找到的form-bean元素,检查它们的类型是否匹配。
如果没找到ActionForm或检查类型不匹配,就根据form-bean元素创建新的ActionForm。
根据scope属性,把ActionForm放到request或session里。
?
13. 填充ActionForm
用请求参数填充对应的ActionForm属性。
?
14. 验证ActionForm
实际上就是调用ActionForm的validate()方法,如果validate()方法返回的ActionErrors不为空,表示没有通过验证,请求将转向到ActionMapping的input属性指定的路径。
如果出现下面的情况之一将跳过这一步:
ActionForm为null;
ActionMapping的validate属性指定为false;
当前请求由点击“取消”按钮(即<html:cancel>)产生。
?
15. 处理Forward
如果ActionMapping设置了forward属性值,请求将转向该属性指定的路径。
?
16. 处理include
如果ActionMapping设置了include属性值,请求将包含该属性指定的路径。
?
17. 获得Action对象
Action对象是ActionMapping的type属性指定类的实例。如果Action对象以前被访问过,可以直接获得该对象;如果没有被访问过,则创建新的Action对象。
?
18. 执行Action的execute()方法
这个execute()方法就是使用Struts的程序员最熟悉的那个方法。
?
19. 处理ActionForward
上面的execute()方法返回一个ActionForward对象,将请求转发或重定向到ActionForward的path属性指定的路径。