一、概念
轻量级的MVC框架,主要解决了请求分发的问题,重心在控制层和表现层。低侵入性,与业务代码的耦合度很低。Struts2实现了MVC(功能模块和显示模块的分离),并提供了一系列 API,采用模式化方式简化业务开发过程。
注:MVC 由 Model(模型),View(视图),Controller(控制器)组成。
① 模型对应 service 层,表示业务数据或业务逻辑。
② 视图对应 如: JSP ,是用户看到并与之交互的界面。
③ 控制器 对应 controller ,根据用户的输入,控制用户界面数据显示和更新 model 对象。
二、框架结构和工作原理
2.1 框架结构
(图片来源见水印)
2.2 工作原理
(1)客户端浏览器发送 HTTP 请求到 Web 应用 。
(2)这个请求经过一系列的过滤器(Filter)到达 StrutsPrepareAndExecuteFilter (核心控制器)(这些过滤器中有一个叫做 ActionContextCleanUp 的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 。
(3)StrutsPrepareAndExecuteFilter 调用 ActionMapper(Action映射器)确定调用哪个Action。
(4)如果有合适的 Action 再将控制权转移给 ActionProxy 代理 。
(5)ActionProxy 通过 Configuration Manager 询问框架的配置文件(开始加载配置文件),找到需要调用的 Action 类,创建一个ActionInvocation的实例。
(6)ActionInvocation 在调用拦截器链中的拦截器后再调用 Action。
(7)根据 Action 返回的结果字符串在 struts.xml 中的配置找到对应的 Result 。返回结果通常是(但不总是,也可能是另外的一个 Action 链)一个需要被表示的JSP或者FreeMarker的模版。再以相反的顺序执行拦截器链,返回HTTP响应 。
(8)HTTP响应以相反的顺序返回给核心控制器 StrutsPrepareAndExecuteFilter 以及其他 web.xml 中定义的过滤器,最终返回给客户端。
FilterDispatch和StrutsPrepareAndExecuteFilter区别?
FilterDispatcher 是 struts 2.0.x到2.1.2版本的核心过滤器,
StrutsPrepareAndExecuteFilter 是自 2.1.3 开始就替代了 FilterDispatcher 。
2.3 工作流程
三、组件说明
ActionMapper:通过 method 参数将请求转发到具体的 action 。
ActionProxy代理:是 Action 的一个代理类,也就是说 Action 的调用是通过 ActionProxy 实现的,其实就是调用了 ActionProxy.execute()方法,而该方法又调用了 ActionInvocation.invoke()方法。归根到底,最后调用的是 DefaultActionInvocation.invokeAction() 方法。
ActionInvocation:就是 Action 的调用者。ActionInvocation 在 Action 的执行过程中,负责 Interceptor、Action和Result 等一系列元素的调度。
Interceptor拦截器:是 Struts2 的一个强有力的工具,有许多功能(feature)都是构建于它之上,如国际化、校验等。
四、参数传递
1.Action从页面取值
a)模型驱动
b)属性驱动
2.页面从Action取值
a)使用EL表达式
取基本属性值 { 属性名 }
取域模型对象值 { 对象 . 属性名 }
b)OGNL
五、其他
Struts2标签库与OGNL表达式
1.背景:在JSP中,为了减少JSP中嵌入大量的Java代码,JSP规范制定了JSP标准标签库JSTL(JSP Standard Tag Library),提高了JSP页面的可读性和可维护性。 而Struts2也有自己独特的标签库,而且更为强大,不仅可以替代JSTL标签库,还适用于任何表示层技术(如Velocity、FreeMarker等)。Strut2默认采用OGNL表达式访问Action的数据,实际上是通过ValueStack对象来访问Action 。类似于EL。
2.注意:在JSP中使用标签库时,需要使用taglib指令引入标签库
2.OGNL 用法:在Struts2中,OGNL表达式要结合Struts2标签来访问数据
EL:${user.userName} <==> OGNL:<s:property value="user.userName">
*a)访问基本属性 <s:property value="属性名"/>
*b)访问实体对象 <s:property value="对象名.属性名"/>
c)访问数组/集合 <s:property value="someArray[1]"/> | <s:property value="someList[1]"/>
d)访问Map <s:property value="someMap.key" />
e)运算 <s:property value="'My name is' + name" />
f)调用方法 <s:property value="name.toUpperCase()" />
g)创建集合 <s:property value="{'a','b','c'}" /> ArrayList
h)创建Map <s:property value="#{'mm':'MM','nn':'NN'}" /> LinkedHashMap
ValueStack
1.概念:是Struts2中,Action向页面传递数据的媒介,封装了Action的数据,并允许JSP通过OGNL来对其访问
2. EL表达式访问ValueStack
a)EL也是从ValueStack中取的值
b)EL默认的取值范围是page,request,session,application
c)Struts2重写的request的getAttribute方法,先试图从原始request中取值,如果没取到再从ValueStack中取值
创建一个ActionInvocation的实例。