1. 简单介绍 Struts2
- 按照 MVC 设计模式设计的 WEB 层框架,在 struts 1 和 WebWork 的技术基础上进行了合并。全新 Struts2 体系结构与Struts 1差别巨大。Struts 2 以WebWork为核心,采用拦截器机制处理用户的请求, 使业务逻辑控制器能够 ServletAPI 完全脱离。
- 可把 struts2 理解为一个大servlet,这servlet 就是ActionServlet。struts2在处理客户端请求时,先读取 web.xml 配置文件,根据前端控制器将符合条件的请求分给各个不同的 Action 处理。 在此之前,会把ActionServlet 会把数据封装成一个 javaBean。
- Struts2 框架提供了许多的拦截器,在封装数据的过程中,我们可以对数据进行一些操 作,如:数据校验等等。
- 当 Action 执行完后要返回一个结果视图,这个结果视图可以跟据 struts2 的配置文件中 配置,选择转发或者重定向。
2. Struts2 的执行流程
关于图中的 Key:
- Servlet Filters:过滤器链,客户端的所有请求都要经过 Filter 链的处理。
- Struts Core:Struts2 的核心部分,但是 Struts2 已经帮我们做好了,我们不需要去做这个
- Interceptors,Struts2 的拦截器。S2 提供了很多默认拦截器,可完成日常开发绝大部分工作;而自定义的拦截器,用来实现实际的客户业务需要的功能。
- User Created,由开发人员创建包括 struts.xml、Action、Template。
说明
- FilterDispatcher是整个 Struts2的调度中心,也是MVC中的 C(控制中心),根据ActionMapper 的结果来决定是否处理请求,如果ActionMapper指出该 URL 应被Struts2 处理,那么它将会执行 Action 处理,并停止过滤器链上还没有执行的过滤器。
- ActionMapper会判断这个请求是否应被 Struts2 处理,如需Struts2 处理,ActionMapper会返回一个对象来描述请求对应的 ActionInvocation 的信息。
- ActionProxy,会创建一个 ActionInvocation 实例,位于Action 和xwork间,使在将来有机会引入更多的实现方式,如通过 WebService 来实现等。
- ConfigurationManager xwork 配置的管理中心,可把它看做 struts.xml 配置文件在内存中的对应。
- struts.xml是 Stuts2 的应用配置文件,负责诸如 URL 与 Action 之间映射关系的配置、及执行后页面跳转的 Result 配置等。
- ActionInvocation:真正调用并执行 Action,有一个 Action实例和这个 Action 所依赖的拦截器实例。会按照指定的顺序去执行这些拦截器、Action 以及相应的 Result。
- Interceptor(拦截器):Stuts2 的基石,类似JavaWeb 的Filter,是一些无状态的类,拦截器可自动拦截 Action,给开发者提供了在 Action 运行前或 Result 运行后来执行一些功能代码的机会。
- Action:用来处理请求,封装数据。
流程
1. 客户端发送一个HTTP请求
2. 该请求被struts2的核心过滤器StrutsPreparedAndExecuteFilter匹配(只要是在过滤器url-pattern中配置了/*,任何请求都会进入该过滤器,无论请求是否需struts2来处理),当然在进入过滤器之前会依次进入在web.xml中配置的位置在struts2过滤器之前的其他Filter或Servlet.
3. struts2的过滤器会询问(调用方法)ActionMapper该请求是否有与之对应的业务控制类,如没,则放行,如有,进入下一步执行流程
4. struts2通过ActionProxy实例化ActionInvocation,当然在这前ActionProxy还会通过ConfigurationManager按序加载struts2的配置文件:default.properties, struts-default.xml, struts.properties, struts.xml…(先加载struts默认的,然后才是自己定义的),正因为加载这些配置文件struts才能找到相应的拦截器以及业务控制类。
5. ActionProxy初始化一个ActionInvocation并通过它的invoke来正式执行一系列的拦截器以及Action,在执行完Action之后会根据使用的模板(jsp, velocity, freemarker…)组装结果集Result,渲染页面
6. 返回给客户端响应
3. Struts2 中 Action 配置的注意事项
- name包名称,struts2 的配置文件中,包名不能重复,name并不是真正包名,只为了管理 Action
- namespace 和
<action>
的 name 属性,决定 Action 的访问路径 (以 / 开始 ) - extends继承哪个包,通常开发中继承 struts-default 包 (struts-default 包 在 struts-default.xml 中定义 )【可使用包中默认的拦截器和结果集】
4. 拦截器和过滤器区别
- 拦截器是基于 java 的反射机制的,而过滤器是基于函数回调
- 拦截器不依赖与 servlet 容器,而过滤器依赖与 servlet 容器
- 拦截器只能对 action 请求起作用,而过滤器则可以对几乎所有的请求起作用
- 拦截器可以访问 action 上下文、值栈里的对象,而过滤器不能
- 在 action 的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一 次
5. Struts2 的封装方式(action接收参数)
struts2中action接收参数的3种方法
详见:https://blog.csdn.net/liyifan687/article/details/80047803
6. Struts2 的值栈
- 是对应每一个请求对象的数据存储中心。struts2一个很重要的特点就是引入了值栈。之前通过缓存或模型驱动在action 和页面间传递数据,数据混乱,且难管理,缓存还有时间,数量限制,使用困难。值栈可统一管理页面和action 之间的数据,供action、result、interceptor等使用。大多数情况不需考虑值栈在哪里,有什么,只需去获取自己需要的数据就可。
7. SpringMVC 和 Struts2 的区别
-
- Struts2 是类级别的拦截, 一个类对应一个 request 上下文.
- SpringMVC 是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应.
- 所以说从架构本身上SpringMVC就容易实现restful url,而struts2的架构实现起来要费劲,因 Struts2 中 Action 的一个方法可以对应一个 url,而其类属性却被所有方法共享,也
就无法用注解或其他方式标识其所属方法了。
- 由上边原因,SpringMVC的方法间基本独立,独享 request response 数据,请求数据通过参数获取,处理结果通过 ModelMap 交回给框架,方法之间不共享变量.
而S2就较乱,虽方法间也独立,但其所有 Action 变量是共享的,不影响程序运行,却给编码读程序时带来麻烦,每次来请求就创建个Action,Action对象对应个 request 上下文。 - 由于 S2 需针对每个 request 进行封装,把 request,session 等 servlet 生命周期的变量封装成一个个 Map,供给每 Action 使用,并保证线程安全,原则上较耗内存。
- 拦截器实现机制上,S2 有以自己的 interceptor 机制,SMVC 用的是独立的 AOP 方式,这样导致Struts2 的配置文件量还比 SpringMVC 大。
- SMVC 的入口是 servlet,Struts2 是 filter(filter 和 servlet 是不同的。),导致二者的机制不同,这里就牵涉到 servlet 和 filter 的区别了。
- SMVC 集成了 Ajax,使用方便,只需注解@ResponseBody 就可实现,直接返回响应文本,而 S2 拦截器集成了 Ajax,在 Action 中处理时一般须安装插件或写代码集成进去.
- SpringMVC 验证支持 JSR303,处理起来相对更加灵活方便,而 Struts2 验证比较繁琐。
- Spring MVC 和 Spring 是无缝的。项目的管理和安全上也比 S2 高(当然 Struts2 也可以通过不同的目录结构和相关配置做到 SpringMVC 一样的效果,但需 xml 配置的地方不少)。
- 设计思想上,S2 更加符合 OOP 的编程思想, SpringMVC较谨慎,在 servlet 上扩展。
- SMVC 开发效率和性能高于 Struts2。
- SMVC 可以认为已经 100%零配置。
8. Struts2 中的 # 和 % 分别是做什么的?
- 使用#获取 context 里面数据
- 向 request 域放值(获取 context 里面数据,写 ognl 时候,首先添加符号#context 的 key 名称.域对象名称)
- 在页面中使用 ognl 获取
- %在 struts2 标签中表单标签
在 struts2 标签里面使用 ognl 表达式,如直接在 struts2 表单标签里面使用 ognl 表达式不识别,只有%之后才会识别。
9. Struts2 常用结果类型
- dispatcher :默认的请求转发的结果类型,Action 转发给 JSP
- chain :Action 转发到另一个 Action (同一次请求)
- redirect : 重定向,重定向到一个路径信息,路径信息没有限制(不在一个请求中),Action 重定向到 JSP
- redirectAction :Action 重定向到另一个 Action
- stream :将原始数据作为流传递回浏览器端,该结果类型对下载的内容和图片非常有用。
- freemarker :呈现 freemarker 模板。
- plaintext :返回普通文本内容。