虽然struts2已经有点过时了,但是企业的旧项目中依然在大量使用,理解struts2其实就是理解struts2的工作原理,很多初学者会回避下边这张图,里边确实有很多陌生的单词,但实际开发中看不懂的部分其实也不用开发人员管,框架早为我们做了处理。好久没用struts2了,复习一下,也希望可以帮到部分初学者:
1.从最顶端开始,客户端发来一个请求HttpServletRequest;
2.请求最先进入一系列的过滤器filter(注意:不是一步直接到ActionMapper),然后进入核心控制器FilterDispatcher,FilterDispatcher判断请求是否符合web.xml中配置的格式,如下图:
(本图为所有请求),
3.如果符合则进入ActionMapper,ActionMapper决定该请求是否需要调用某个action;
4.如果需要,FilterDispatcher把请求交给代理对象ActionProxy;
5.ActionProxy通过Configuration Manager询问框架的配置文件struts.xml,找到需要调用的Action类;
6.ActionProxy创建一个ActionInvocation实例,用来调用action,但是在调用之前要先执行拦截器,而默认的拦截器就在struts-default.xml文件里,struts.xml文件的package又默认继承struts-default.xml,如图:
从图中也可以看出,Interceptor的定义和使用的最大范围是package,这就类似于类,变量和方法的定义和使用必须在类里;
7.struts2的执行是基于拦截器的,每个struts2请求在进入action之前都要经过默认拦截器和用户自定义的拦截器(如果用户不配置拦截器则使用默认拦截器),如果不经过默认拦截器则请求的参数无法到达action,如果用户自己配置了拦截器,在自定义拦截器之后一定要执行默认拦截器,因为用户配置了拦截器之后默认拦截器就会失效,必须手动添加,如图:
如果把默认拦截器注释掉只保留用户配置的拦截器,则相关参数无法到达action,比如文件上传中的文件,文件名,文件类型等,类似于重定向;
ActionInvocation里有invoke()方法,该方法会调用拦截器Interceptor中的intercept(ActionInvocation ai)方法,intercept()方法是拦截器的核心方法,方法体内又会调用ai.invoke()方法,直到最后一个拦截器调用之后才进入action,如图:,
action执行之后带着返回结果又继续执行intercept()方法的剩余部分,可以在这儿对返回结果做进一步处理;这就是为什么会先执行Interceptor1,2,3再执行Action,带着返回结果找到result,然后还会执行Interceptor3,2,1的原因;
8.将响应HttpServletResponse返回客户端,请求结束。