嗯,又要开始......了
一、前言
1.1 Struts2的概述
Struts2是一个基于MVC设计模式的WEB层框架。
Struts2的内核相对于Struts1来讲已经发生巨大变化。
1.2 常见的web层框架
- Struts2 (常用)
- Struts1
- Webwork
- SpringMVC (常用)
1.2 Web层框架基于前端控制器模型设计
二、入门
2.1 下载Struts2的开发环境
2.2 解压Struts2开发包
- apps :Struts2提供的应用,war文件:web项目打成war包。直接放入到tomcat可以允许。
- docs :Struts2的开发文档和API
- lib :Strtus2框架的开发的jar包
- src :Struts2的源码
2.3 创建web项目,引入jar包
引入jar包,struts-blank项目下找到jar包
2.4 创建一个JSP页面
2.5 编写Action类
2.6 对Action进行配置
在src下创建(提供)名称叫做struts.xml的配置文件
2.7 配置前端控制器(核心过滤器)
2.8 改写Action中的方法的返回值
2.9 改写struts.xml
2.10 编写success.jsp
三、执行流程及常见配置
3.1 分析Struts2的执行流程
Struts2的执行流程
当用户访问某一个Action的时候,先经过核心过滤器,在核心过滤器中执行一组拦截器(这组拦截器实现部分功能),执行目标Action,根据Action的返回值,进行页面跳转。
3.2 Struts2的常见配置
1.struts2的配置文件加载顺序(了解)
init_DefaultProperties() ----加载default.properties
init_TraditionalXmlConfigurations(); ----加载struts-default.xml、struts-plugin.xml、struts.xml
init_LegacyStrutsProperties(); ----加载struts.properties
init_CustomConfigurationProviders(); ----加载配置提供类
init_FilterInitParameters() ; // [6] ----加载web.xml中过滤器初始化参数
init_AliasStandardObjects() ; // [7] ----加载Bean对象
2.加载顺序
default.properties
struts-default.xml
struts-plugin.xml
struts.xml
struts.properties
web.xml
注意:后配置的常量的值会覆盖先配置的常量的值。
3.Action的配置
- package相关配置
package标签称为包,这个包与Java中的包的概念不一致。包为了更好管理action的配置。
package标签的属性
name :包的名称,只有在一个项目中不重名即可。
extends :继承哪个包,通常值为struts-default。
namespace :名称空间,与<action>标签中的name属性共同决定访问路径。
名称空间有三种写法:
带名称的名称空间 :namespace=”/aaa”
跟名称空间 :namespance=”/”
默认名称空间 :namespace=””
abstract :抽象的,用于其他包的继承。
- action相关配置
action标签配置Action类。
action标签的属性
name :与namespace共同决定访问路径
class :Action类的全路径
method :执行Action中的哪个方法的方法名,默认值execute
converter :用于设置类型转换器
4.Struts2的常量配置
在Struts2的框架中,提供了非常多的常量:(在default.properties)
struts.i18n.encoding=UTF-8 ----Struts2中所有的post请求的中文乱码不用处理。
struts.action.extension=action,, ----Struts2请求的默认的扩展名。默认扩展名是.action或者什么都不写。
在Struts2中修改一些常量的值
修改常量的值,可以有三个位置进行修正
-
struts.xml中进行修改
-
struts.properties中进行修改
-
web.xml中进行修改
注:多处配置与配置文件的加载顺序有关,最后加载配置生效(标准配置在struts.xml中)
5.分模块开发include的配置
6.Action的访问
6.1 Action的写法
-
Action类是POJO的类
-
Action类实现一个Action的接口
-
Action类继承ActionSupport类(标准)
6.2 Action的访问
-
通过method设置
-
通过通配符的方式进行配置
-
通配符更抽象写法
-
动态方法访问
四、Struts2的数据封装及Servlet的API访问
4.1 Struts2的Servlet的API的访问
在使用Struts2的框架的过程中,发现Struts2和Servlet的API是解耦合的。在实际开发中,经常使用到Servlet的API,比如进行登录,将用户的信息保存到Session中,有的时候需要向页面输出一些内容,用到response对象。涉及到Servlet的API的访问。
4.1.1 完全解耦和的方式(常用)
-
注意:这种方式只能获得代表request、session、application的数据的Map集合,不能操作这些对象的本身的方法。
4.1.2 使用Servlet的API的原生方式(常用)
-
注意:这种方式可以操作域对象的数据,同时也可以获得对象的方法。
4.1.3 接口注入的方式(不常用)
-
Servlet是单例的,多个程序访问同一个Servlet只会创建一个Servlet的实例。Action是多例的,一次请求,创建一个Action的实例(不会出现线程安全的问题)。
4.2 结果页面及result标签的配置
4.2.1 全局结果页面
- 全局结果页面:全局结果页面指的是,在包中配置一次,其他的在这个包中的所有的action只要返回了这个值,都可以跳转到这个页面。
-
针对这个包下的所有的action的配置都有效。
4.2.2 局部结果页面
- 局部结果页面:局部结果页面指的是,只能在当前的action中的配置有效。
-
针对当前的action有效。
4.2.3 result标签的配置
result标签用于配置页面的跳转。在result标签上有两个属性:
name属性 :逻辑视图的名称。默认值:success
type属性 :页面跳转的类型。
dispatcher :默认值,请求转发。(Action转发JSP)
redirect :重定向。(Action重定向JSP)
chain :转发。(Action转发Action)
redirectAction :重定向。(Action重定向Action)
stream :Struts2中提供文件下载的功能。
4.3 Struts2的数据封装
- 模型驱动方式最常用的方式:
- 缺点:只能同时向一个对象中封装数据。
- 使用第二种可以向多个对象中同时封装数据:
4.3.1 属性驱动:提供属性set方法的方式(不常用)
-
编写页面
-
编写Action
4.3.2 属性驱动:页面中提供表达式方式
-
编写JSP
-
编写Action
4.3.3 模型驱动:采用模型驱动方式(最常用)
-
编写JSP
-
编写Action
4.3.4 关于input逻辑视图
Action接口中提供了五个逻辑视图的名称:
- SUCCESS
- ERROR
- LOGIN
- INPUT :input在某些拦截器中会使用。
- NONE
4.3.5 封装数据到List集合中
-
编写JSP
-
编写Action
4.3.6 封装数据到List集合中
-
编写JSP
-
编写Action
五、OGNL及值栈
5.1 OGNL概述
5.1.1 概述
- OGNL:对象图导航语言,比EL表达式强大很多倍的语言
- EL:从域对象中获取数据,从EL的11个对象中获取。${}
- OGNL:调用对象的方法,获取Struts2的值栈数据,OGNL其实是第三方的表达式语言。
5.1.2 为什么学习OGNL
5.1.3 OGNL的要素
- 表达式
- 根对象
- Context对象
5.2 OGNL的Java环境入门(了解)
5.2.1 访问对象的方法
5.2.2 访问对象的静态方法
5.2.3 获得Root中的数据(不需要加#)
5.2.4 获得OgnlContext中的数据(需要加#)
5.3 OGNL的Struts2环境入门
5.3.1 访问对象的方法
5.3.2 访问对象的静态方法
5.4 值栈
5.4.1 什么是值栈
ValueStack是Struts的一个接口,字面意义为值栈,OgnlValueStack是ValueStack的实现类,
客户端发起一个请求Struts2架构会创建一个action实例同时创建一个OgnlValueStack值栈实例,
OgnlValueStack贯穿整个Action的生命周期,struts2中使用OGNL将请求Action的参数封装
为对象存储到值栈中,并通过OGNL表达式读取值栈中的对象属性值
- ValueStack 其实类似于一个数据中转站(Struts2的框架当中的数据都保存到了ValueStack中)。
- ValueStack 接口,实现类OgnlValueStack对象。
- ValueStack 贯穿整个Action的生命周期。(Action一旦创建了,框架就会创建一个ValueStack对象)。
5.4.2 值栈的内部结构
ValueStack中有两个主要的区域:
- root区域:其实就是一个ArrayList。里面一般放置对象,不需要加#
- context区域:其实就是一个Map。里面放置是web开发的常用对象数据的引用,需要加#
- request
- session
- application
- parameters
- attr
所说的操作值栈,通常指的是操作的ValueStack中的root区域
5.4.3 值栈与ActionContext的关系
- ServletContext:Servlet的上下文
- ActionContext:Action的上下文
- 通过源码查看到:当请求过来的时候,执行过滤器中doFilter方法,在这个方法中创建ActionContext;在创建ActionContext过程中,创建ValueStack对象,将ValueStack对象传递给ActionContext对象。所以可以通过ActionContext获取值栈对象。
- ActionContext对象之所以能够访问Servlet的API(访问是对象的数据)。因为在其内部有值栈的引用
5.4.4 获得值栈
- 通过ActionContext对象获取值栈
-
在Struts2的内部,将值栈存入request中一份
5.4.5 操作值栈--向值栈种存入数据
- 一种:在Action中提供属性的get方法的方式(不常用,默认不在栈顶,相同名称会出问题)
-
默认情況下,将Action对象压入到值栈。Action的属性呢?(也会在值栈中)
-
-
二种:使用ValueStack中本身的方法的方式(常用,默认栈顶)
5.4.6 获取值栈数据
- 获取值栈中的数据就是在页面中使用OGNL表达式即可。
-
获取root的数据:不需要加#
-
获取context数据:需要加#
-
5.4.7 EL为何能访问值栈数据
因为Struts2的框架的底层对request.getAttribute(String name);增强了
5.5 OGNL中特殊字符
5.5.1 #号
- 获取context的数据
-
使用#号构建map集合
5.5.1 %号
- 强制解析OGNL
-
强制不解析OGNL(没用)
5.5.1 $号
- 在配置文件中使用OGNL
- 属性文件
- 国际化地方:
- message_zh_CN.properties
user.login=登录
user.welcome=欢迎,${#session.user.username} - message_en_US.properties
user.login=Login
user.welcome=Welcome,${#session.user.username}
- message_zh_CN.properties
- 国际化地方:
- XML文件
- 文件下载
- 配置
<action name="download" class="xxx.DownloadAction">
<result type="stream">
<param name="Content-Type">文件类型</param>
<param name="Content-Disposition">attachment;filename=${文件名}</param>
</result>
</action>
- 配置
- 文件下载
- 属性文件
六、拦截器及标签库(结)
6.1 Struts2的拦截器
6.1.1 什么是拦截器
- Interceptor:拦截器,起到拦截Action的作用。
- Filter:过滤器,过滤从客户端向服务器发送的请求。
- Interceptor:拦截器,拦截是客户端对Action的访问。更细粒度化的拦截。(拦截Action中的具体的方法)。
- Struts2框架核心的功能都是依赖拦截器实现。
6.1.2 Struts2的执行流程
客户端向服务器发送一个Action的请求,执行核心过滤器(doFilter)方法。在这个方法中,调用executeAction()方法,在这个方法内部调用dispatcher.serviceAction();在这个方法内部创建一个Action代理,最终执行的是Action代理中的execute(),在代理中执行的execute方法中调用ActionInvocation的invoke方法。在这个方法内部递归执行一组拦截器(完成部分功能),如果没有下一个拦截器,就会执行目标Action,根据Action的返回的结果进行页面跳转。
6.1.3 拦截器入门
-
编写拦截器类
编写一个类实现Interceptor接口或者继承AbstractInterceptor类。
- 对拦截器进行配置
-
定义拦截器进行配置
-
定义一个拦截器栈的方式
-
6.2 Struts2的标签库
6.2.1 通用标签库
- 其他常用的标签
- <s:property/>
- <s:debug/>
- <s:date />----在页面上进行日期格式化。