Struts2 总结
1.控制器采用的是 Filter 这个服务器端组件,相比于 Servlet ,Servlet 能获取到的资源,Filter 也同样能获取到,不同的是 Filter 生命周期初始化和 Servlet 有所区别。
2.Struts2 使用 Filter 和 Interceptors 完成了表述层要解决的常见问题,如异常处理,防止表单重复提交,文件上传下载,类型转换,国际化等。
而自定义的拦截器又为其他问题进行了扩展。
3.Struts2 使用 ValueStack 和 ModelDriven 使开发更加便捷。
ValueStack 可以看成是 Struts2 的一个容器,也可以看成是 表述层的一个容器。
结合 OGNL 表达式和 Struts2 标签,可以在页面中获取到任何想获取到的资源,比如域对象中的信息,请求参数,Web资源等,错误信息等。
而 ModelDriven 为请求参数提供了一种基于对象的注入,使开发更加便捷。
4.每一个 Struts2 请求会对应一个 ValueStack(它存在于整个 Action 生命周期内,在 Struts2 请求接受到请求的时候创建,随请求的结束而结束),对应一个
Action 对象,对应一个 action(实际处理请求的方法) 请求,保证了线程之间的安全性,但是也极大的消耗了服务器资源。
5.Struts2 是这样运行的:
(1)在 Web 应用启动时,执行了 Struts2 的核心 Filter(StrutsPrepareAndExecuteFilter) 的初始化方法,接受到一个请求时,执行 doFilter() 方法,在 doFilter()
方法中,先对请求和响应对象进行了强转,转为对应的 HttpServletXxx 对象,然后判断这个请求如果不是一个 Struts2 请求,则直接放行。如果是一个 Struts2 请求,
则根据请求内容的类型不同而包装为不同的 请求包装类对象。如果为 multipart/form-data 类型,则返回对应的包装类型 MultiPartRequestWrapper,其他情况下
返回 StrutsRequestWrapper 对象,request 对象重新包装过后,通过 ActionMapper 的 getMapping() 方法得到ActionMapping,如果 mapping 为空,判断
请求的是否为静态资源,若为静态资源,则直接放行。若 mapping 不为空,则执行 Action,Action的配置信息存储在 ActionMapping 对象中。
将调用 Dispatcher.serviceAction()方法。如图:
(2)在 Dispatcher.serviceAction()方法中,做了两件事。
一是根据给定的参数,创建了 ActionContext,以及 ValueStack 的获取(如果已经存在一个ValueStack,则复制一份到新的 Action 请求中)。
二是:在配置信息加载完成后,创建 ActionProxy 对象(Action 的代理对象)。
ActionProxy 是由 ActionProxyFactory 创建,ActionProxyFactory是创建 ActionProxy 的工厂。
其中ActionProxy 和 ActionProxyFactory 都是借口,默认实现为:DefaultActionProxy 和 DefaultActionProxyFactory,在 xwork2 包下。
在 DefaultActionProxy 中,实际向后调用的是 ActionInvocation 的 invoke() 方法。
DefaultActionInvocation 作为 ActionInvocation 的默认实现。在 DefaultActionInvocation的 invoke() 方法中,实现了拦截器的递归调用和
执行目标 Action 的 execute() 方法。其中递归调用拦截器的代码如下:
if (interceptors.hasNext()) { final InterceptorMapping interceptor = interceptors.next(); String interceptorMsg = "interceptor: " + interceptor.getName(); UtilTimerStack.push(interceptorMsg); try { resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); } finally { UtilTimerStack.pop(interceptorMsg); } }
如果拦截器全部执行完毕,则调用 invokeActionOnly() 方法执行目标 Action。最后调用的是 DefaultActionInvocation.invokeAction() 方法。调用关系如下:
ActionProxy:管理了 Action 的生命周期。
ActionInvocation:在 ActionProxy 层下,是真正干活的。
最后通过 Result 进行页面的跳转。
6.Struts 中需要添加配置文件的几个地方。
(1)struts.xml 文件,如果需要按照模块划分的话,还需要增加对应的配置文件。
(2)修改主题模板
(3)自定义类型转换器。Action 级别和 全局级别是配置方式是不一样的。
(4)输入验证。同样的有两种方式,一种是对当前 Action 类的所有 action 使用同样的验证规则,二种是对当前 Action 类的具体某个 action 使用验证规则。
(5)国际化资源文件
(5)自定义拦截器
7.在我看来的 Struts2 优缺点:
优点:
Struts2 为常见的 Web 方面的问题提供了解决方案,拦截器和值栈作为核心,在页面中又有 Struts2 自己的标签,思想比较简单,也便于开发。
在看Struts2 源码的时候,发现它的命名特别易懂。同时 Struts2 源码也比较易读。
缺点:
配置繁琐,往往是每个 Action 对应一个配置文件。
只能进行属性的验证,不能对 model 进行验证。
虽然对当前 表述层存在的问题都进行了解决,但是开发起来还是比较繁琐。
simple 主题也含有默认样式。
未完,待续。