大致上 ,Struts2 框架由三个部分组成 : 核心控制器 FilterDispatcher, 业务控制器和用户实现的业务逻辑组件 . 在这三个部分里面 ,Struts2 框架提供了核心控制器 FilterDispatcher, 而用户需要提供业务控制器和业务逻辑组件 .
(1) 核心控制器 FilterDispatcher
FilterDIspatcher 是 Struts2 框架的核心的控制器 , 该控制器作为一个 Filter 运行在 Web 应用当中 , 它负责拦截所有的用户请求 , 当用户请求到达的时候 , 该 Filter 将会过滤用户请求 . 如果用户请求以 action 结尾 , 那么 , 该请求将被转入 Struts2 框架处理 .
Struts2 框架获得了 *.action 请求之后 , 将会根据 *.action 请求的前面的部分决定调用哪个业务逻辑组件 , 比如说 , 对于 login.action 请求 ,Struts2 调用名为 login 的 Action 来处理该请求 .
Struts2 应用中的 Action 都被定义到 struts.xml 文件当中了 , 在该文件中定义 Action 的时候 , 定义了该 Action 的 name 属性和 class 属性 , 其中 name 属性决定了改 action 处理哪个用户的请求 . 而 struts 框架提供了系列拦截器 , 该系列拦截器负责将 HttpServletRequest 请求中的请求参数解析出来 , 传入到 Action 当中 , 并且回调 Action 的 execute 方法来处理用户的请求 .
显然 , 上面的处理过程是典型的 AOP 处理方式 .( 面向切面编程 ), 用户实现的 Action 类仅仅是 Struts2 的 Action 代理的代理目标 . 用户实现的业务控制器 Action 则包含了对用户请求的处理 . 用户的请求数据包含在 HttpServletRequest 对象里面 , 而用户的 Action 类无需访问 HttpServletRequest 对象 , 拦截器负责将 HttpServletRequest 里面的请求数据解析出来 , 并且传给业务逻辑组件 Action 实例 .
(2) 业务控制器
业务控制器组件就是用户实现的 Action 类的实例 ,Action 中通常包含了一个 execute 方法 , 该方法返回一个字符串 — 这个字符串就是一个逻辑视图名 , 当业务控制器处理完用户的请求之后 , 根据处理的结果不同 ,execute 方法就返回不同的字符串 — 每个字符串对应一个视图名 .
程序员开发出系统所需要的业务控制器之后 , 还需要配置 struts2 的 Action, 也就是配置 Action 的如下三个部分的定义 :
1) Action 所要处理的 URL
2) Action 组件所对应的实现类
3) Action 里面包含的逻辑视图和物理资源之间的关系
每个 Action 都要处理一个用户的请求 , 而用户请求总是包含了指定的 URL, 当 FilterDispatcher 拦截到用户的请求之后 , 根据请求的 URL 和 Action 处理 URL 之间的对应关系来进行转发 .
(3) Struts2 的模型组件
JavaEE 应用里的模型组件 , 通常是指业务逻辑组件 , 而隐藏在系统业务逻辑组件下面的 , 还可能包含了 DAO, 领域对象等组件 .
通常 MVC 框架里面的业务控制器会调用模型组件的方法来处理用户请求 . 也就是说 , 业务逻辑控制器不会对用户请求进行任何的实际处理 . 用户请求最终由模型组件负责处理 . 业务控制器只是中间负责调度的调度器 , 这也是称 Action 为控制器的原因 .( 当控制器需要获得业务逻辑组件的实例的时候 , 通常不会直接获取业务逻辑组件实例 , 而是通过工厂模式来获得业务逻辑组件的实例 , 或者利用其他 IOC 容器 , 比如说 Spring 容器来管理业务逻辑的实例 )
请求发送到容器 - à FilterDispatcher- à 转发请求 - à Action-- à 业务逻辑组件
(4) Struts2 的视图组件
Struts2 已经改变了 Struts1 只能够使用 JSP 作为视图技术的现状 ,Struts2 允许使用其他的模版模式 , 比如说 FreeMarker,Velocity 等作为视图技术 .
当 Struts2 的控制器返回逻辑视图名的时候 , 逻辑视图并没有和任何的视图技术相关联 , 仅仅是返回一个字符串 , 该字符串作为逻辑视图名
当我们在 struts.xml 文件中配置 Action 的时候 , 不仅要制定 Action 的 name 属性和 class 属性 , 还要为 Action 元素指定 result 子元素 , 每个 result 子元素定义一个逻辑视图和物理视图之间的映射 .
如果需要在 Struts2 中使用其他的视图技术 , 则可以再配置 result 子元素的时候 , 指定相应的 type 属性就可以了 , 比如说 , 要使用 FreeMarker, 则为 result 指定 freeMarker 的 type 属性 , 如果想使用 velocity 模版技术作为视图资源 , 则为 result 指定值为 velocity 的 type 属性 ……
(5) Struts2 的运行流程
Struts2 框架的运行流程非常类似于 WebWork 的流程 .