文章目录
MVC设计模式概览
实现MVC(Model、View、Controller
)模式的应用程序由三大部分组成:
- 模型:封装应用程序的数据和业务逻辑POJO(普通java类)
- 视图:实现应用程序的信息显示功能JSP
- 控制器:接收来自用户的输入,调用模型层,响应对应的视图组件Servlet、Filter
使用Filter作为控制器的MVC
使用Filter作为控制器的好处:
可以方便的在应用程序里对所有资源(包括静态资源)进行控制访问。
Servlet VS Filter:
- Servlet能做的Filter都可以完成
- Filter能做的Servlet不可以都完成,拦截资源不是Servlet所擅长的,Filter中有一个FilterChain,这个API在Servlet中没有。
过程介绍
需求:
核心部分:
步骤:
- 由
product-input.action
转到/WEB-INF/pages/input.jsp
在 struts2 中配置一个 action:
<action name="product-input">
<result>/WEB-INF/pages/input.jsp</result>
</action>
- 由 input.jsp 页面的
action: product-save.action
到Product's save
, 再到/WEB-INF/pages/details.jsp
<action name="product-save" class="com.atguigu.struts2.helloworld.Product"
method="save">
<result name="details">/WEB-INF/pages/details.jsp</result>
</action>
在 Prodcut 中定义一个 save 方法, 且返回值为 details.
通过反射的方式创建实例
Action概述
action
代表一个Struts2的请求。
Action类
能够处理Struts2请求的类。
- 属性的名字必须遵守JavaBeans属性名相同的命名规则,属性的类型可以是任意类型的,从字符串到非字符串(基本数据类型)之间的数据转换可以自动发生。
- 必须有一个不带参的构造器(通过反射创建实例)
- 至少有一个供struts在执行这个action时调用的方法
- 同一个Action类可以包含多个action方法
- Struts2会为每一个HTTP请求创建一个新的Action实例(即Action不是单例的,是线程安全的)
在Action中访问Web资源
1. 什么是Web资源?
HttpServletRequest、HttpSession、ServletContext
等原生的Servlet API.
2. 为什么访问Web资源?
B\S的应用的Controller
中必然需要访问WEB资源:向域对象中读写属性,读写Cookie,获取realPath…
3. 如何访问?
(1)和Servlet API解耦的方式:只能访问有限的Servlet API对象,且只能访问其有限的方法(读取请求参数、读取域对象的属性、使session失效。。。)Struts2对HttpServletRequest、HttpSession、ServletContext
进行了封装,构造了三个Map对象来替代这三个对象,在Action中可以直接使用HttpServletRequest、HttpSession、ServletContext
对应的Map对象来保存和读取数据。
- 使用
ActionContext
- 使用
XxxAware
接口
选用的建议:
若一个Action类中有多个action方法,且多个方法都需要使用域对象的Map或parameters,则建议使用Aware接口的方式。
(2)和Servlet API耦合的方式:可以访问更多的Servlet API对象,且可以调用其原生的方法。
名为params
的拦截器获取请求参数,并将请求参数赋给了一个Bean的对应属性。
- 使用
ServletActionContext
可以从中获取到当前Action对象需要的一切Servlet API相关的对象。
常用的方法:
(1)获取HttpServletRequest
:ServletActionContext.getRequest();
(2)获取HttpSession
:ServletActionContext.getRequest().getSession();
(3)获取ServletContext
:ServletActionContext.getServletContext();
- 使用
ServletXxxAware
接口
通过实现ServletXxxAware
接口的方式可以由Struts2注入需要的Servlet相关的对象:
ServletRequestAware
:注入HttpServletRequest
对象(比较常用)
ServletContexAware
:注入ServletContext
对象(比较常用)
ServletResponseAware
:注入HttpServletResponse
对象
ActionSupport
该类是默认的Action类。若某个action没有配置class属性,则ActionSupport即为待执行的Action类,而execute方法即为要默认执行的action方法。
在手工完成字段验证,显示错误消息,国际化等情况下,推荐继承ActionSupport。
result
- result 是 action 节点的子节点
- result 代表 action 方法执行后, 可能去的一个目的地
- 一个 action 节点可以配置多个 result 子节点.
- result 的 name 属性值对应着 action 方法可能有的一个返回值
- result 一共有 2 个属性, 还有一个是 type: 表示结果的响应类型
- result 的 type 属性值在 struts-default 包的 result-types 节点的 name 属性中定义
常用的有:dispatcher
(默认的): 转发,同 Servlet 中的转发.。该结果类型将把控制权转发给应用程序里的指定资源,不能把控制权转发给一个外部资源,若需要把控制权重定向到一个外部资源,应该使用redirecth结果类型。
redirect
: 重定向,把响应重定向到另一个资源,而不是转发给该资源,有两个参数:
(1)location:用来给出重定向的目的地,是默认属性
(2)parse:用来表明是否把location参数视为一个OGNL表达式来解释,默认值为true。
redirectAction
: 把响应重定向到另一个 Action
注意: 通过 redirect 的响应类型也可以便捷的实现 redirectAction 的功能!
chain
: 构成一个action链:前一个action把控制权转发给后一个action,而前一个action的状态在后一个action中依然保持,参数method用于指定目标action方法,默认值为execute。
注意: 不能通过 type=dispatcher 的方式转发到一个 Action
这里需要补充一下重定向和转发的区别:
- 重定向访问服务器两次,转发只访问服务器一次。
- 转发页面的URL不会改变,而重定向地址会改变
- 转发只能转发到自己的web应用里,重定向可以重定向到任意资源路径
- 转发相当于服务器跳转,相当于方法调用,在执行当前文件的过程中转向执行目标文件,两个文件(当前文件和目标文件)属于同一次请求,前后页共用一个request,可以通过此来传递一些数据或者session信息,
request.setAttribute()
和request.getAttribute()
,而重定向会产生一个新的request,不能共享request域信息与请求参数。- 由于转发相当于服务器内部方法调用,所以转发后面的代码仍然会执行(转发之后记得return);重定向代码执行之后是方法执行完成之后进行重定向操作,也就是访问第二个请求,如果是方法的最后一行进行重定向那就会马上进行重定向(重定向也需要return)。
- 无论是
RequestDispatcher.forward
方法还是HttpServletResponse.sendRedirect
方法,在调用他们之前,都不能有内容已经被实际输出到客户端。如果缓冲区中已经有了一些内容,这些内容将被从缓冲区中移除。
通配符映射
将多个相关的action配置为一个action节点,即多个struts请求用一个action节点。
动态方法调用
通过URL动态调用Action中的方法。
默认情况下,Struts的动态方法调用处于禁用状态。