1. 简单介绍一下Struts2
Struts2 框架是一个按照 MVC 设计模式设计的 WEB 层框架,是在 struts 1 和 WebWork 的技术基础上进行了合并的全新的框架。其全新的 Struts 2 的体系结构与 Struts 1 的体 系结构差别巨大。Struts 2 以 WebWork 为核心,采用拦截器的机制来处理用户的请求, 这样的设计也使得业务逻辑控制器能够与 ServletAPI 完全脱离开。
我们可以把 struts2 理解为一个大大的 servlet,而这个 servlet 就是 ActionServlet。struts2 在处理客户端请求时,会先读取 web.xml 配置文件,根据前端控制器将符合条件的请求 分给各个不同的 Action 处理。 在此之前,会把 ActionServlet 会把数据封装成一个 javaBean。
Struts2 框架提供了许多的拦截器,在封装数据的过程中,我们可以对数据进行一些操 作,例如:数据校验等等。
当 Action 执行完后要返回一个结果视图,这个结果视图可以跟据 struts2 的配置文件中 配置,选择转发或者重定向。
2. Struts2的执行流程了解么?
Struts2的官方文档附带了Struts2的架构图。从这张图可以很好的去理解Struts2
关于图中的Key:
Servlet Filters:过滤器链,客户端的所有请求都要经过Filter链的处理。
Struts Core:Struts2的核心部分,但是Struts2已经帮我们做好了,我们不需要去做这个
Interceptors:Struts2的拦截器。Struts2提供了很多默认的拦截器,可以完成日常开发的绝大部分工作;而我们自定义的拦截器,用来实现实际的客户业务需要的功能。
User Created,由开发人员创建的,包括struts.xml、Action、Template,这些是每个使用Struts2来进行开发的人员都必须会的。
- 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 所依赖的拦截器实例。ActionInvocation会按照指定的顺序去执行这些拦截器、Action以及相应的Result。 Interceptor(拦截器):是 Struts2 的基石,类似于 JavaWeb 的 Filter,拦截器是一些无状态的类,拦截器可以自动拦截Action,它们给开发者提供了在Action运行之前或Result运行之后来执行一些功能代码的机会。
- Action:用来处理请求,封装数据。
参考资料:http://blog.csdn.net/wjw0130/article/details/46371847
3. Struts2中Action配置的注意事项有哪些?
- name 包名称,在 struts2 的配置文件中,包名不能重复,name 并不是真正包名,只是为 了管理 Action
- namespace 和 的 name 属性,决定 Action 的访问路径 (以/开始 )
- extends 继承哪个包,通常开发中继承 struts-default 包 (struts-default 包 在 struts-default.xml 中定义 )【可以使用包中默认的拦截器和结果集】
4. 拦截器和过滤器有哪些区别?
-
拦截器是基于 java 的反射机制的,而过滤器是基于函数回调
-
拦截器不依赖与 servlet 容器,而过滤器依赖与 servlet 容器
-
拦截器只能对 action 请求起作用,而过滤器则可以对几乎所有的请求起作用
-
拦截器可以访问 action 上下文、值栈里的对象,而过滤器不能
-
在 action 的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一 次
5. Struts2的封装方式有哪些?
一、属性封装
- 在action中设置成员变量,变量名与表单中的name属性值相同
- 生成变量的set方法
实例:获取用户输入的用户名和密码
jsp页面如下:
java代码如下:
二、模型驱动(常用)
- action实现 ModeDriven 接口
- 在action里创建实体类对象
- 实现接口的 getModel方法并返回所创建的对象
示例:获取用户输入的用户名和密码
jsp页面如下:
java代码如下:
需注意的是表单 name 的值应与类的属性名相同。
三、表达式封装
- 在 action 中声明实体类
- 生成实体类的 set 和 get 方法
- 在表单输入项的 name 属性值里面写表达式
jsp页面如下:
java代码如下:
6. 简单介绍一下Struts2的值栈。
值栈是对应每一个请求对象的数据存储中心。Struts2的一个很重要的特点就是引入了值栈。之前我们通过缓存或者模型驱动在action和页面之间传递数据,数据混乱,并且难以管理,缓存还有时间和数量限制,使用起来非常的困难。值栈的引入解决了这个问题,它可以统一管理页面和action之间的数据,供action、result、interceptor等使用。我们大多数情 况下不需要考虑值栈在哪里,里面有什么,只需要去获取自己需要的数据就可以了,大大的降低了开发人员的工作量和逻辑复杂性。
参考资料:https://www.cnblogs.com/hlhdidi/p/6185836.html
7. SpringMVC和Struts2的区别?
1、Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上SpringMVC就容易实现restful url,而struts2的架构实现起来要费劲,因为 Struts2 中 Action 的一个方法可以对应一个 url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。
2、由上边原因,SpringMVC的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过 ModelMap 交回给框架,方法之间不共享变量,而 Struts2 搞的就比较乱,虽然方法之间也是独立的,但其所有 Action 变量是共享的,这不会影响程序运行,却给我们编码 读程序时带来麻烦,每次来了请求就创建一个Action,一个Action对象对应一个request上下文。
3、由于Struts2需要针对每个request进行封装,把request,session等servlet生命周期的变量封装成一个一个Map,供给每个Action使用,并保证线程安全,所以在原则上,是比较耗费内存的。
4、 拦截器实现机制上,Struts2有以自己的interceptor机制,SpringMVC用的是独立的AOP方式,这样导致Struts2的配置文件量还是比SpringMVC大。
5、SpringMVC 的入口是servlet,而Struts2 是 filter(这里要指出,filter 和servlet 是不同的。),这就导致了二者的机制不同,这里就牵涉到servlet和filter的区别了。
6、SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在 Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。
7、SpringMVC验证支持JSR303,处理起来相对更加灵活方便,而Struts2验证比较繁琐,感觉太烦乱。
8、Spring MVC 和 Spring 是无缝的。从这个项目的管理和安全上也比 Struts2 高(当然 Struts2 也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。
9、 设计思想上,Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。
10、SpringMVC开发效率和性能高于Struts2。
11、SpringMVC可以认为已经100%零配置。
8. Struts2中的 # 和 % 分别是做什么的?
(1)使用#获取context里面数据
<s:iterator value = "list" var="user">
<s:property value = "#user.username"/>
</s:iterator>
(2)向 request域放值(获取context里面数据,写ognl时候,首先添加符号#context的key名称.域对象名称)
(3)在页面中使用ognl获取
<s:property value = "#request.req"/>
(4)%在struts2标签中表单标签
在struts2标签里面使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只有%之后才会识别。
<s:textfield name="username" value="%{#request.req}"/>
9. Struts2中有哪些常用结果类型?
1)dispatcher :默认的请求转发的结果类型,Action 转发给 JSP
2)chain :Action转发到另一个Action (同一次请求)
3) redirect : 重定向,重定向到一个路径信息,路径信息没有限制(不在一个请求中),Action重定向到 JSP
4) redirectAction :Action重定向到另一个Action
5)stream :将原始数据作为流传递回浏览器端,该结果类型对下载的内容和图片非常有用。
6)freemarker :呈现freemarker模板。
7)plaintext :返回普通文本内容。
欢迎关注作者的公众号《Java编程生活》,每日记载Java程序猿工作中遇到的问题