本文绝对原创, 欢迎转载, 但是转载请记得注明文章出处:http://blog.csdn.net/izard999/article/details/39891281
近4年都在从事Android方 面的工作, 最近换到一家单位做技术主管, 拿到外包的代码发现是Struts2做的, 5年之前对Struts2还是有一定见解的, 但是由于多年不用, 导致还是有些小淡忘, 翻出以前记录的一些笔记和心得, 再加上从官方文档又看到一些版本更新带来的一些新东西, 于是决定再次深入研究一次. 也希望此系列文章能给用得到的朋友们带来实质性的帮助.
好了, 言归正传.
为什么要深入研究, 为什么要学习原理?磨刀不误砍柴工,但是大多数人还是不愿意磨刀,而是先上山砍柴,先过把瘾,等砍几下砍不动了,再下山来磨刀,这样会很耽误时间的.!为什么我会先学习struts2的底层原理,而不是一上来就直接去学习如何用struts2去完成一个个功能呢?表面看起来,直接学习如何用struts2完成功能,看到效果是很爽的事情!但是为什么要这样做?程序代码为什么要这样写?而且一旦Struts2本身就有bug,该如何解决(5年之前我玩2.1.6的时候bug就一堆)?结果不言而喻,稀里糊涂什么都不知道!我是一个喜欢问为什么的人,所以我必须要弄明白为什么,才能举一反三,自己独立做程序,出错了也不慌.!如果等到糊涂了,知道要学底层原理的时候再来学底层原理的话,岂不是跟先砍柴后磨刀一样了,更耽误时间了吗?为什么许多人翻了好多书,学了好几个月struts2还没学明白? 就是学习顺序不对造成的!
Struts2是什么?
Struts2是一个按照MVC模式设计的web层框架,其实Struts2就是一个大大的filter,我们可以在web.xml文件中讲符合某 种特征的所有请求交给这个filter处理,这个filter再参照一个配置文件(通常为/WEB-INF/classes/struts.xml)将各 个请求分别分配给不同的action去处理!
Struts2的核心FilterDispatcher, 从2.1.3版本开始, 换成了StrutsPrepareAndExecuteFilter. 官方为什么要做这个升级呢?
首先看下官方给的Struts2工作原理图:
这个我对Struts官方还是有点意见的, 这个是我在Struts2.3.16.3版本上找的图, 跟我5年前看到的一模一样, 请问您过滤器版本都换了, 这个图也该换换了吧?
Struts2工作原理(基于看完上图的理解):当一个HttpServletRequest请求来了,先经过 ActionContextCleanUp过滤器,清除Action环境,再经过其他的过滤器,例如说SiteMesh和用户自定义过滤器等等, 最后到达Struts2的核心过滤器StrutsPrepareAndExecuteFilter,此 时,StrutsPrepareAndExecuteFilter会去找ActionMapping看此Action路径是否存在,如果存在,则会参照 Struts.xml文件产生Action的代理,并且执行Action,Struts2很多功能是靠拦截器完成的,所以这个Action代理真正调用 Action的处理请求的方法的时候会经过拦截器1,2,3,才真正调用Action的方法,Action方法结束后会返回一个视图,视图也会去参照 ActionMapping,还会参照Template(JSP,FreeMarker),此时,拦截器会再次拦截(说明Struts2的拦截器是进入 Action和返回结果的时候都会拦截的,这比Filter好!),最后产生HttpServletResponse,相应结果!
我们也看到了, 老版本上面, 我们需要的别的过滤器全部要放在Struts2的过滤器之前. 但是我现在有个需求: 我想在我的过滤器里面做一些事,需要Struts2的环境(ActionContext), 但是又需要在Struts2的Action执行之前. 这个时候, 老版本的那个过滤器就只能两眼望青天了.
打个比方, 好比一个病人要做手术, 做手术需要打麻药(自定义过滤器)和动手术(Struts2的过滤器), 请问打麻药要怎么打呢? 不能让病人站着吧.. 所以首先要准备一个床(ActionContext), 之后打麻药, 再手术. 这也就是StrutsPrepareAndExecuteFilter真正的含义. 可以分成StrutsPrepareFilter,StrutsExecuteFilter, 如果没有像之前那样的需求,我们一般都用StrutsPrepareAndExecuteFilter就可以了.
稍后请关注下一篇: StrutsPrepareAndExecuteFilter源码解读