MVC 设计模式概览
- 实现 MVC(Model、View、Controller) 模式的应用程序由 3 大部分构成:
- 模型:封装应用程序的数据和业务逻辑 POJO(Plain Old Java Object)
- 视图:实现应用程序的信息显示功能JSP
- 控制器:接收来自用户的输入,调用模型层,响应对应的视图组件Servlet Filter
使用 Filter 作为控制器的 MVC
- 使用 Filter 作为控制器的好处
- 使用一个过滤器来作为控制器, 可以方便地在应用程序里对所有资源(包括静态资源)进行控制访问.
<url-pattern>*.action</url-pattern>
Servlet VS Filter
- Servlet 能做的Filter 是否都可以完成? 嗯。
- Filter 能做的Servlet 都可以完成吗? 拦截资源却不是Servlet 所擅长的! Filter 中有一个FilterChain,这个API 在Servlet 中没有!
Struts2 概述
- Struts2 是一个用来开发 MVC 应用程序的框架. 它提供了 Web 应用程序开发过程中的一些常见问题的解决方案:
- 对来自用户的输入数据进行合法性验证
- 统一的布局
- 可扩展性
- 国际化和本地化
- 支持 Ajax
- 表单的重复提交
- 文件的上传下载
- …..
Struts2 VS Struts1
- 在体系结构方面更优秀:
- 类更少, 更高效: 在Struts2 中无需使用“ActionForm”来封装请求参数.
- 扩展更容易: Struts2 通过拦截器完成了框架的大部分工作. 在 Struts2 中插入一个拦截器对象相当简便易行.
- 更容易测试:
- 即使不使用浏览器也可以对基于 Struts2 的应用进行测试
从 Struts1 升级到 Struts2
- Struts2 从本质上讲已不是从 Struts1 扩展而来的, 说它是一个换了品牌标签的 WebWork更合适
- 从 Struts1 升级到 Struts2:
- Struts1 里使用 ActionServlet 作为控制器; Struts2 使用了一个过滤器作为控制器
- Struts1 中每个 HTML 表单都对应一个 ActionForm 实例. Struts2 中, HTML 表单将被直接映射到一个 POJO.
- Struts1 的验证逻辑编写在 ActionForm 中; Struts2 中的验证逻辑编写在 Action 中.
- Struts1 中, Action 类必须继承 org.apache.struts.action.Action 类; Struts2 中任何一个 POJO 都可以是一个 Action 类.
- Struts2 在页面里使用 OGNL 来显示各种对象模型, 可以不再使用 EL 和 JSTL
搭建 Struts2 的环境:
- 加入 jar 包: 复制 struts\apps\struts2-blank\WEB-INF\lib 下的所有 jar 包到当前 web 应用的 lib 目录下.
- 在 web.xml 文件中配置 struts2: 复制 struts\apps\struts2-blank1\WEB-INF\web.xml 文件中的过滤器的配置到当前 web 应用的 web.xml 文件中
- 在当前 web 应用的 classpath 下添加 struts2 的配置文件 struts.xml: 复制 struts1\apps\struts2-blank\WEB-INF\classes 下的 struts.xml 文件到当前 web 应用的 src 目录下.
添加 DTD 约束:
Action 类
- action: 应用程序可以完成的每一个操作. 例如: 显示一个登陆表单; 把产品信息保存起来
- Action类: 普通的 Java 类, 可以有属性和方法, 同时必须遵守下面这些规则:
- 属性的名字必须遵守与 JavaBeans 属性名相同的命名规则.属性的类型可以是任意类型. 从字符串到非字符串(基本数据库类型)之间的数据转换可以自动发生
- 必须有一个不带参的构造器
- 至少有一个供 struts 在执行这个 action 时调用的方法
- 同一个 Action 类可以包含多个 action 方法.
- Struts2 会为每一个 HTTP 请求创建一个新的 Action 实例
访问 web 资源
- 在 Action 中, 可以通过以下方式访问 web 的 HttpSession, HttpServletRequest, HttpServletResponse 等资源
-
与 Se r vlet API 解耦的访问方式
-
- 通过com.opensymphony.xwork2.ActionContext
- 通过 Action 实现如下接口
- 与 Servlet API 耦合的访问方式
- 通过org.apache.struts2.ServletActionContext
- 通过实现对应的 XxxAware接口
与Servlet API解耦的访问方式
- 为了避免与 Servlet API 耦合在一起, 方便 Action 做单元测试, Struts2 对 HttpServletRequest, HttpSession和 ServletContext进行了封装, 构造了 3 个 Map 对象来替代这 3 个对象, 在 Action 中可以直接使用 HttpServletRequest, HttpServletSession, ServletContext对应的 Map 对象来保存和读取数据.
通过 ActionContext访问 Web 资源
- ActionContext是 Action 执行的上下文对象, 在 ActionContext中保存了 Action 执行所需要的所有对象, 包括 parameters, request, session, application 等.
- 获取 HttpSession对应的 Map 对象:
- 获取 ServletContext对应的 Map 对象:
- 获取请求参数对应的 Map 对象:
- 获取 HttpServletRequest对应的 Map 对象:
通过实现 Aware 接口访问 Web 资源
- Action 类通过可以实现某些特定的接口, 让 Struts2 框架在运行时向 Action 实例注入parameters, request, session 和 application 对应的 Map 对象:
与 Servlet耦合的访问方式
- 直接访问 Servlet API 将使 Action 与 Servlet环境耦合在一起, 测试时需要有 Servlet容器, 不便于对 Action 的单元测试.
- 直接获取 HttpServletRequest对象:
- 直接获取 HttpSession对象
- 直接获取 ServletContext对象
- 通过实现 ServletRequestAware, ServletContextAware等接口的方式
ActionSupport
- com.opensymphony.xwork2.ActionSupport 类是默认的 Action 类.
- 在编写 Action 类时, 通常会对这个类进行扩展
result
-
每个 action 方法都将返回一个 String 类型的值, Struts 将根据这个值来决定响应什么结果.
-
每个 action 声明都必须包含有数量足够多的 result 元素 , 每个 result 元素分别对应着 action 方法的一个返回值 .
-
result 元素可以有下面两个属性
-
name: 结果的名字 , 必须与 Action 方法的返回值相匹配 , 默认值为 success
- type: 响应结果的类型. 默认值为 dispatcher
-
结果类型: dispatcher
- dispatcher 结果类型是最常用的结果类型, 也是 struts 框架默认的结果类型
- 该结果类型有一个 location 参数, 它是一个默认参数
- dispatcher 结果类型将把控制权转发给应用程序里的指定资源.
- dispatcher 结果类型不能把控制权转发给一个外部资源. 若需要把控制权重定向到一个外部资源, 应该使用 redirect 结果类型
结果类型: redirect
- redirect 结果类型将把响应重定向到另一个资源, 而不是转发给该资源.
- redirect 结果类型接受下面这些参数:
- location: 用来给出重定向的目的地.它是默认属性
- parse: 用来表明是否把 location 参数的值视为一个 OGNL表达式来解释. 默认值为 true
- redirect 结果类型可以把响应重定向到一个外部资源
结果类型: redirectAction
- redirectAction结果类型把响应重定向到另一个 Action
- redirectAction结果类型接受下面这些参数:
- actionName: 指定 “目的地” action 的名字. 它是默认属性
- namespace: 用来指定 “目的地” action 的命名空间. 如果没有配置该参数, Struts 会把当前 Action 所在的命名空间作为 “目的地” 的命名空间
结果类型: chain
- chain 结果类型的基本用途是构成一个 action 链: 前一个 action 把控制权转发给后一个 action, 而前一个 action 的状态在后一个 action 中依然保持
- chain 结果类型接受下面这些参数:
–
actionName
:
指定目标
action
的名字
.
它是默认属性
–
namespace:
用来指定 “目的地”
action
的命名空间
.
如果没有配置该参数
, Struts
会把当前
action
所在的命名空间作为 “目的地” 的命名空间
–
method:
指定目标
action
方法
.
默认值为
execute
通配符映射
- 一个 Web 应用可能有成百上千个 action 声明. 可以利用 struts 提供的通配符映射机制把多个彼此相似的映射关系简化为一个映射关系
- 通配符映射规则
–
若找到多个匹配
,
没有通配符的那个将胜出
–
若指定的动作不存在
, Struts
将会尝试把这个
URI
与任何一个包含着通配符
*
的动作名及进行匹配
–
被通配符匹配到的
URI
字符串的子串可以用
{1}, {2}
来引用
. {1}
匹配第一个子串
, {2}
匹配第二个子串
…
–
{0}
匹配整个
URI
–
若
Struts
找到的带有通配符的匹配不止一个
,
则按先后顺序进行
匹配
–
*
可以匹配零个或多个字符
,
但不包括
/
字符
.
如果想把
/
字符包括在内
,
需要使用 **
.
如果需要对某个字符进行转义
,
需要使用
\.
动态方法调用
- 动态方法调用: 通过 url动态调用 Action 中的方法
- action 声明:
- URI:
– /struts-app2/ Product !save .action : Struts 调用 Product 类的 save() 方法
- 默认情况下, Struts 的动态方法调用处于禁用状态