1 struts2是在webwork的基础上发展起来的
2 struts2与struts1的比较
1 核心控制器改为了过滤器
2 struts1要求我们的业务控制器必须继承action或者dispatchaction struts2不强制你这么做
只需提供一个返回string类型的execute方法的javabean
3 绑定值到业务类 struts1 通过actionform struts2直接绑定到action属性
4 struts1严重依赖于servlet struts2则不然
5 管理action struts1 单例 struts2 每个请求产生一个实例 (原型)
6 从表达式的支持上,struts2不仅支持jstl,还支持功能更为强大的ognl表达式
7 strust1类型转换是单向的(页面到ActionForm),strust2双向类型转换(页面----action----页面回显)
8 校验 strust没有针对具体方法的校验。当然它有自己的针对path验证
9 struts2支持的视图技术除了jsp之外 还有freemaker velocity 源代码等 stuts1只是单一的表现层技术jsp
3 action的搜索顺序
http://localhost:8080/struts2/ttt/aaa/bbb/ccc/login.action
1 /ttt/aaa/bbb/ccc当做命名空间去搜索 login 如果找不到
2 /ttt/aaa/bbb 如果找不到
3 /ttt/aaa 如果找不到
4 /ttt
5 默认
现在你访问的路径中寻找对应的命名空间,如果找到了,则在当前命名空间下可以逐层访问,如果找不到则递归向上搜索
4 struts1中有以下配置--------------------引出struts2中的各项默认值
<action paht="/login" forward="add.jsp"/>
1struts2的默认result的name是success
2默认的处理方法时execute
3默认的处理类是ActionSupport
4默认的result-type是dispatcher
5 ActionSupport与Action
Action接口提供了5个常量
public static final String SUCCESS = "success";
public static final String ERROR = "error";
public static final String LOGIN = "login";
public static final String INPUT = "input";
public static final String NONE = "none";
ActionSupport
1实现了Action接口
2实现了国际化
3实现了校验
6 动态方法
1 感叹号定位方法
2 配置多个action method指定方法
3 通配符匹配方法 匹配到 方法 类 result
7 标签 action属性get方法 根据get方法后面的字符串属性获取值 反射
<s:property value="ognl的表达式"> 比如说action中的属性名是有效的ognl表达式
<s:url id=“xxx” action="tanglib" namespace="/aaa">
<s:param name="id" value="133"></s:param>
。。。。
</s:url>
<s:a href="%{xxx}">战三</s:a>----------特殊的ognl取值
<s:bean name="类全名" id="yyy" ></s:bean>
<s:bean name="com.lxit.taglib.PersonList" id="yyy" ></s:bean>
<s:set name="ooo" value="#yyy" scope="session" ></s:set>
8 模型驱动与属性驱动
action类实现 ModelDriven<javabean类名> 接口,采用泛型
在 action类中定义javabean属性,实现getModel方法
7 struts2国际化
action范围-----包范围-----全局国际化
action类简单名字------package_zh.properties-----------ApplicationResources.properties
全局国际化的原理
struts2通过i18n的一个拦截器获得请求参数request_locale的值(如zh或en) 并把当前获得的值转化为Locale对象,
并把该locale对象存储在名为WW_TRANS_I18N_LOCALE的session作用域中,根据struts2的流程处理,拦截器只会在执行
action的时候调用,所以如果我们直接访问jsp,并没有进入struts2的action执行流程,拦截器也不会起作用,所以我们一般
把对jsp的访问转化为多action的访问,通过如下配置可达到该目的
<action name="*">
<result>/{1}.jsp
</action>
经过该配置后,如果我们要访问add.jsp可以通过add.action进行
8 struts2 类型转换
内建的类型转换器
基本数据类型 String list map set ognl
自定义的类型转化器
从技术的实现角度划分
1基于OGNL的实现 继承DefaultTypeConverter
2基于struts2自己的实现StrutsTypeConverter
注册类型转换器
从范围来说
1局部类型转换器 自己action使用 action同目录下建立Action简单类名-conversion.properties
2全局类型转换器 全部action使用 src建立xwork-conversion.properties
当类型转化出错的时候,struts2会寻找input指定的result 我们用<s:fielderor/>进行显示错误
???????//自定义的类型转换器不能显示???????????、
长生原因:我们在程序中捕获异常,我们并没有把异常重新抛出,这时候,struts2认为程序正常执行,为什么我们不能抛出
编译时异常,因为重写了父类的方法,父类方法没有异常抛出,子类不能抛出比父类更多的编译期异常,为此我们把编译时异常
转化成运行时异常将其抛出
9 struts2校验
1 继承ActionSupport 重写validate方法或者编写validatetXxx 方法,重写哦vaildate方法会对Action中的所有struts2业务方法进行校验
2 校验框架<字段与非字段>
在action的同目录下编写Action简单类名-validation.xml文件,该文件中的验证会对对Action中的所有struts2业务方法进行校验,如要校验某个方法
编写的文件名是Action简单类名-action name(struts,xml配置中的name)-validation.xml文件
3 校验流程
3.1 将请求参数进行类型转换
3.2 判断类型转换是否出现异常,如果出现异常,利用ConvesionError拦截器将其加入到fieldError中,并保存到ActionContext
3.3 调用validateXXX方法
3.4 调用validate方法
3.5 判断是否存在fieldError,如果存在,寻找input指定的result返回
3.6 如果不存在fieldError,执行action中的业务方法
10 ognl object graphic navigator language 对象图形导航语言
相对于jstl或者其他表达式语言,它有如下优势
1 能够调用对象实例的方法 比如person.doXxx() 如
PersonAction p=new PersonAction();
p.setUserName("张三");
p.setAge(100);
Map map=new HashMap();
Person p1=new Person();
p1.setName("王五");
map.put("aaa", p1);
map.put("bbb", "222");
System.out.println(Ognl.getValue("aaa()", map , p));
2 能够调用类的静态方法@类全名@方法名 或者访问常量@类全名@常量名
3 操作集合对象 如list map
<s:radion list="{'aa','bb','cc'}"/> <s:radion list="#{'aa':'11','bb':'22','cc':'33'}"/>
4 访问Ognl上下文,在struts2中ognl上下文的对应实现者为ActionContext( action 上下文),在struts2中要依靠它的标签才能使用ognl
如<s:property value="ognl表达式"/? 由于属性名是有效的ognl表达式所以我们经常有以下写法
<s:prtperty value="age"/>
actioncontext包含以下内容
1根对象 就是值栈 里面有一个list属性放action实例 一般我们当前访问的action实例会放在栈顶
以下值得访问需要加命名空间#
2parameters
3request
4session
5application
6attr
5 struts2中默认的表达式语言就是ognl
每次你访问一个action时,struts2会为创建一个map 一个ActionContext 一个action action实例放到根对象值栈中栈顶
把parameters request session application attr放入map中 访问map(ognl上下文)中对象要加命名空间#,值栈直接访问
CompoundRoot list=new CompoundRoot();
list.push(action实例);
ValueStack valueStack=new OgnlValueStack();
System.out.println(Ognl.getValue("userName", map , list));
6 ognl3个常用的符号 # $ %
# 1构造map 2取ognl上下文的值
3用来过滤集合
<s:iterator value="list.{?#this.age>200}">
<s:property value="name"/>
<s:property value="age"/><br>
</s:iterator>
$ 1 在校验框架中去资源文件中的值 2用来传递参数
% 当你的表达式为字符串时,计算里面的值 如<s:href value='%{url}'/> %{getText('key',{'11','22'})}
11 strust2如何访问servlet api
1 第一种访问方式 直接访问 非ioc访问
访问session或者是aplication通过ActionContext.getContext().getSession ActionContext.getContext().getApplication
访问request通过ServletActionContext.getrequest()
2 ioc inverse of control 控制反转
要访问request 实现ServletrequestAware接口 实现setServletRequest方法 在我们的action中定义一个HttpServletRequest request;
public void setServletRequest(HttpServletRequest request) {
// TODO Auto-generated method stub
this.request=request;
}
要访问session 类似
12 拦截器
在访问类的某个方法或者属性之前,进行拦截然后在方法的执行前或者之后加入某些操作
代理模式:3种角色 1目标对象2抽象角色3代理角色
原来的调用 客户端-------目标对象方法 学了代理模式之后 客户端----代理对象----目标对象
涉及到两个问题
1客户端 要调用代理对象 如何创建代理对象的问题
代理对象中 直接new代理类
2代理对象要调用目标对象 代理对象必须持有目标对象实例
3 因为我们是通过代理对象调用目标对象,所以我们希望代理对象和目标对象有共同的方法为此我们提出了抽象角色的概念,用接口来是想
代理类与目标类都实现同一个接口
代理可以代理一个接口下的所有子类 由此可以看出,当需要代理的接口越来越多的时候,我们的代理类会急剧膨胀,
此时我们通过jdk动态代理来解决这个问题,这就涉及到如何创建一个动态代理对象
Proxy.newProxyInstance(类加载器,类所属的所有接口,InvocationHandle)
1 目标对象类加载器
2 目标对象类所属的所有接口
3 InvocationHandle 要求我们的动态代理类必须实现的接口
动态代理类里面有一个Object属性 供我们传入目标对象实例
有一个必须实现的方法 invoke 此时我们通过反射调用我们自己传入实例的方法
//调用之前加入某些操作
method。invoke(obj,args)//回调我们传入的实例的方法
//调用之后加入某些操作
为什么1 客户端有时候不可以直接调用目标对象 2 加入一些操作
拦截器属于低侵入式设计
13 关于ActionInvocation 类的分析 核心方法 invoke
如果存在拦截器 则执行拦截器的intercept方法
interceptor(ActionInvocation actionInvocation)
interceptor 方法又执行actionInvocation的invoke方法 此时又进入了先判断当前的迭代器里是否还有拦截器
如果没有拦截器 则直接执行action类业务方法 业务方法返回一个string 所以inoke方法也返回一个srring
从以上代码我们可以看出 struts2是通过一种A类调用B类 B类又调用A类的 非传统递归的方式完成拦截器的调用
14 result 的类型
结果类型(result-type)
说明
dispatcher 默认的
用于与jsp整合的结果类型
plaintext
用于显示某个页面原始代码的结果类型
redirect
用于直接跳转到其他URL的结果类型
redirect-action
用于直接跳转到其他Action的结果类型
chain
Action链式处理的结果类型(两个action之间有一定的数据传递关系)
stream
用于向浏览器返回一个InputStream的结果类型
freemarker
用于与FreeMarker整合的结果类型
httpheader
用于控制特殊的HTTP行为的结果类型
velocity
用于整合Velocity的结果类型
xslt
用于整合XML/XSLT的结果类型
15 为什么el表达式能够取得action的属性值 这是为什么呢?
打印request对象的类名,它是struts2提供的一个HttpServletRequest的包装类,这个类重写了getAttribute方法,
这个包装的request对象的getAttribute方法除了找自己的attribute集合,还去ValueStack,
即可以从ValueStack中的各个对象上获取属性。当前的Action又是放在ValueStack的栈顶上的,
所以,在jsp页面中也可以使用${}来获得Action的属性。
查看StrutsRequestWrapper的源码,可以验证上面这个思路。
16 最大的特点的就是脱离的servletAPI
ActionContext每一次执行所产生的数据,也就是依赖的环境
将servletAPI的放在ActionCotext
ActionContext.getContext();返回自己本身
get put --->map request作用域
getSession()-->map session作用
getApplication-->map appliction
getValueStack 值栈
类型转换错误
国际化
使用ThreadLocal模式来解决每次请求的ActionContext是独立的
17 Struts2的结果集类型:
action不配置class的时候,默认的处理类是ActionSupport 默认的处理方法是execute
返回值name默认为success result默认type是dispatcher
18。 struts2如何封装servlet?
在Dispatcher里面调用createContext封装servletAPI,并在里面通过extracContext.put方法,把servletAPI放入actionContext中
通过继承AbstractMap,定义了一个自己的map类,在get方法里面调用了request.getAttribute(key.toString);方法
所以在ActionContext.getContext().get();的时候其实就是调用了request.getAttribute(key.toString);方法
19.requestMap等servletapi如何跟ActionContext挂钩(联系)的?
1、根对象
以下访问要加#号,因为是用map封装的
2、parameters
3、request
4、session
5、application
6、attr,先拿request的值,拿不到时就去拿session的,拿不到session的就去拿application
20.、Ognl表达式
Map map = new HashMap();
map.put("aaa","2222");
Person person = new Person();
person.setName("张三");
拿map中值,Ognl.getValue("#aaa",map,person);
那根里面的值,也就是值栈里面的值.Ognl.getValue("name",map,person);
这就是为什么struts2为什么要把servletAPI封装成map的原因,因为ognl必须这样
21、ActionContext如何保证线程安全?
ThreadLocal
actionContext是放在ThreadLocal里面的,以保证线程安全
新张老师课堂总结:{
Administrator 11:36:20 (多人发送)
actioncontext是被存放在当前线程中的,获取ActionContext也是从ThreadLocal中获取的。所以在执行拦截器、 action和result的过程中,
由于他们都是在一个线程中按照顺序执行的,所以可以可以在任意时候在ThreadLocal中获取 ActionContext。
ActionContext包括了很多信息,比如Session、Application、Request、Locale、ValueStack等,
其中 ValueStack可以解析ognl表达式,来动态去一些值,同时可以给表达式提供对象。值栈是建立在ognl的基础之上的。
Administrator 11:36:27 (多人发送)
1 Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
返回 extraContext 该map信息如下
把 servlet 中paramtert request session application 转换成map,这样struts2就脱离了servlet api
并且 把我们转化后的一个个map放入ActionContext,同时在返回的extraContextke中有paramter,request,session,application,attr
这些key值所对应的value值就是上面的一个个map
还有 一个attr AttributeMap request-sessio-application
}
22. struts1无法验证指定的方法,只能验证form或path,而struts2提供了对指定方法validateXXX方法的验证。但是验证了指定validateXXX方法
后,还是会验证validate方法,那么如果跳过validate方法呢?可以使用注解、零配置做到,对方法进行标记,xml配置时无法做到的
@SkipValidation //配置指定方法跳过验证
@InputConfig(resultName="add") //出现错误跳回<result name="add"></result>的页面
@InputConfig(nethodName="xxx") //指定出现错误跳入那个方法,并根据方法的返回值进入result
public String xxx(){
return "input"
}
使用注解配置拦截器:
@InterceptorRef(value="timer") //配置拦截器timer,执行这个action所需要的时间
拦截器的注解使用,比较使用的
@Before(priority=1)
@After()
令牌机制
token:
<s:token/>
<result name="invalid.token">/add.jsp</result>
<interceptor-ref name="token"></interceptor-ref>
tokenSession:比token好用,不需要指定result并且不会产生<s:actionerror/>信息
<interceptor-ref name="tokenSession"></interceptor-ref>
2 struts2与struts1的比较
1 核心控制器改为了过滤器
2 struts1要求我们的业务控制器必须继承action或者dispatchaction struts2不强制你这么做
只需提供一个返回string类型的execute方法的javabean
3 绑定值到业务类 struts1 通过actionform struts2直接绑定到action属性
4 struts1严重依赖于servlet struts2则不然
5 管理action struts1 单例 struts2 每个请求产生一个实例 (原型)
6 从表达式的支持上,struts2不仅支持jstl,还支持功能更为强大的ognl表达式
7 strust1类型转换是单向的(页面到ActionForm),strust2双向类型转换(页面----action----页面回显)
8 校验 strust没有针对具体方法的校验。当然它有自己的针对path验证
9 struts2支持的视图技术除了jsp之外 还有freemaker velocity 源代码等 stuts1只是单一的表现层技术jsp
3 action的搜索顺序
http://localhost:8080/struts2/ttt/aaa/bbb/ccc/login.action
1 /ttt/aaa/bbb/ccc当做命名空间去搜索 login 如果找不到
2 /ttt/aaa/bbb 如果找不到
3 /ttt/aaa 如果找不到
4 /ttt
5 默认
现在你访问的路径中寻找对应的命名空间,如果找到了,则在当前命名空间下可以逐层访问,如果找不到则递归向上搜索
4 struts1中有以下配置--------------------引出struts2中的各项默认值
<action paht="/login" forward="add.jsp"/>
1struts2的默认result的name是success
2默认的处理方法时execute
3默认的处理类是ActionSupport
4默认的result-type是dispatcher
5 ActionSupport与Action
Action接口提供了5个常量
public static final String SUCCESS = "success";
public static final String ERROR = "error";
public static final String LOGIN = "login";
public static final String INPUT = "input";
public static final String NONE = "none";
ActionSupport
1实现了Action接口
2实现了国际化
3实现了校验
6 动态方法
1 感叹号定位方法
2 配置多个action method指定方法
3 通配符匹配方法 匹配到 方法 类 result
7 标签 action属性get方法 根据get方法后面的字符串属性获取值 反射
<s:property value="ognl的表达式"> 比如说action中的属性名是有效的ognl表达式
<s:url id=“xxx” action="tanglib" namespace="/aaa">
<s:param name="id" value="133"></s:param>
。。。。
</s:url>
<s:a href="%{xxx}">战三</s:a>----------特殊的ognl取值
<s:bean name="类全名" id="yyy" ></s:bean>
<s:bean name="com.lxit.taglib.PersonList" id="yyy" ></s:bean>
<s:set name="ooo" value="#yyy" scope="session" ></s:set>
8 模型驱动与属性驱动
action类实现 ModelDriven<javabean类名> 接口,采用泛型
在 action类中定义javabean属性,实现getModel方法
7 struts2国际化
action范围-----包范围-----全局国际化
action类简单名字------package_zh.properties-----------ApplicationResources.properties
全局国际化的原理
struts2通过i18n的一个拦截器获得请求参数request_locale的值(如zh或en) 并把当前获得的值转化为Locale对象,
并把该locale对象存储在名为WW_TRANS_I18N_LOCALE的session作用域中,根据struts2的流程处理,拦截器只会在执行
action的时候调用,所以如果我们直接访问jsp,并没有进入struts2的action执行流程,拦截器也不会起作用,所以我们一般
把对jsp的访问转化为多action的访问,通过如下配置可达到该目的
<action name="*">
<result>/{1}.jsp
</action>
经过该配置后,如果我们要访问add.jsp可以通过add.action进行
8 struts2 类型转换
内建的类型转换器
基本数据类型 String list map set ognl
自定义的类型转化器
从技术的实现角度划分
1基于OGNL的实现 继承DefaultTypeConverter
2基于struts2自己的实现StrutsTypeConverter
注册类型转换器
从范围来说
1局部类型转换器 自己action使用 action同目录下建立Action简单类名-conversion.properties
2全局类型转换器 全部action使用 src建立xwork-conversion.properties
当类型转化出错的时候,struts2会寻找input指定的result 我们用<s:fielderor/>进行显示错误
???????//自定义的类型转换器不能显示???????????、
长生原因:我们在程序中捕获异常,我们并没有把异常重新抛出,这时候,struts2认为程序正常执行,为什么我们不能抛出
编译时异常,因为重写了父类的方法,父类方法没有异常抛出,子类不能抛出比父类更多的编译期异常,为此我们把编译时异常
转化成运行时异常将其抛出
9 struts2校验
1 继承ActionSupport 重写validate方法或者编写validatetXxx 方法,重写哦vaildate方法会对Action中的所有struts2业务方法进行校验
2 校验框架<字段与非字段>
在action的同目录下编写Action简单类名-validation.xml文件,该文件中的验证会对对Action中的所有struts2业务方法进行校验,如要校验某个方法
编写的文件名是Action简单类名-action name(struts,xml配置中的name)-validation.xml文件
3 校验流程
3.1 将请求参数进行类型转换
3.2 判断类型转换是否出现异常,如果出现异常,利用ConvesionError拦截器将其加入到fieldError中,并保存到ActionContext
3.3 调用validateXXX方法
3.4 调用validate方法
3.5 判断是否存在fieldError,如果存在,寻找input指定的result返回
3.6 如果不存在fieldError,执行action中的业务方法
10 ognl object graphic navigator language 对象图形导航语言
相对于jstl或者其他表达式语言,它有如下优势
1 能够调用对象实例的方法 比如person.doXxx() 如
PersonAction p=new PersonAction();
p.setUserName("张三");
p.setAge(100);
Map map=new HashMap();
Person p1=new Person();
p1.setName("王五");
map.put("aaa", p1);
map.put("bbb", "222");
System.out.println(Ognl.getValue("aaa()", map , p));
2 能够调用类的静态方法@类全名@方法名 或者访问常量@类全名@常量名
3 操作集合对象 如list map
<s:radion list="{'aa','bb','cc'}"/> <s:radion list="#{'aa':'11','bb':'22','cc':'33'}"/>
4 访问Ognl上下文,在struts2中ognl上下文的对应实现者为ActionContext( action 上下文),在struts2中要依靠它的标签才能使用ognl
如<s:property value="ognl表达式"/? 由于属性名是有效的ognl表达式所以我们经常有以下写法
<s:prtperty value="age"/>
actioncontext包含以下内容
1根对象 就是值栈 里面有一个list属性放action实例 一般我们当前访问的action实例会放在栈顶
以下值得访问需要加命名空间#
2parameters
3request
4session
5application
6attr
5 struts2中默认的表达式语言就是ognl
每次你访问一个action时,struts2会为创建一个map 一个ActionContext 一个action action实例放到根对象值栈中栈顶
把parameters request session application attr放入map中 访问map(ognl上下文)中对象要加命名空间#,值栈直接访问
CompoundRoot list=new CompoundRoot();
list.push(action实例);
ValueStack valueStack=new OgnlValueStack();
System.out.println(Ognl.getValue("userName", map , list));
6 ognl3个常用的符号 # $ %
# 1构造map 2取ognl上下文的值
3用来过滤集合
<s:iterator value="list.{?#this.age>200}">
<s:property value="name"/>
<s:property value="age"/><br>
</s:iterator>
$ 1 在校验框架中去资源文件中的值 2用来传递参数
% 当你的表达式为字符串时,计算里面的值 如<s:href value='%{url}'/> %{getText('key',{'11','22'})}
11 strust2如何访问servlet api
1 第一种访问方式 直接访问 非ioc访问
访问session或者是aplication通过ActionContext.getContext().getSession ActionContext.getContext().getApplication
访问request通过ServletActionContext.getrequest()
2 ioc inverse of control 控制反转
要访问request 实现ServletrequestAware接口 实现setServletRequest方法 在我们的action中定义一个HttpServletRequest request;
public void setServletRequest(HttpServletRequest request) {
// TODO Auto-generated method stub
this.request=request;
}
要访问session 类似
12 拦截器
在访问类的某个方法或者属性之前,进行拦截然后在方法的执行前或者之后加入某些操作
代理模式:3种角色 1目标对象2抽象角色3代理角色
原来的调用 客户端-------目标对象方法 学了代理模式之后 客户端----代理对象----目标对象
涉及到两个问题
1客户端 要调用代理对象 如何创建代理对象的问题
代理对象中 直接new代理类
2代理对象要调用目标对象 代理对象必须持有目标对象实例
3 因为我们是通过代理对象调用目标对象,所以我们希望代理对象和目标对象有共同的方法为此我们提出了抽象角色的概念,用接口来是想
代理类与目标类都实现同一个接口
代理可以代理一个接口下的所有子类 由此可以看出,当需要代理的接口越来越多的时候,我们的代理类会急剧膨胀,
此时我们通过jdk动态代理来解决这个问题,这就涉及到如何创建一个动态代理对象
Proxy.newProxyInstance(类加载器,类所属的所有接口,InvocationHandle)
1 目标对象类加载器
2 目标对象类所属的所有接口
3 InvocationHandle 要求我们的动态代理类必须实现的接口
动态代理类里面有一个Object属性 供我们传入目标对象实例
有一个必须实现的方法 invoke 此时我们通过反射调用我们自己传入实例的方法
//调用之前加入某些操作
method。invoke(obj,args)//回调我们传入的实例的方法
//调用之后加入某些操作
为什么1 客户端有时候不可以直接调用目标对象 2 加入一些操作
拦截器属于低侵入式设计
13 关于ActionInvocation 类的分析 核心方法 invoke
如果存在拦截器 则执行拦截器的intercept方法
interceptor(ActionInvocation actionInvocation)
interceptor 方法又执行actionInvocation的invoke方法 此时又进入了先判断当前的迭代器里是否还有拦截器
如果没有拦截器 则直接执行action类业务方法 业务方法返回一个string 所以inoke方法也返回一个srring
从以上代码我们可以看出 struts2是通过一种A类调用B类 B类又调用A类的 非传统递归的方式完成拦截器的调用
14 result 的类型
结果类型(result-type)
说明
dispatcher 默认的
用于与jsp整合的结果类型
plaintext
用于显示某个页面原始代码的结果类型
redirect
用于直接跳转到其他URL的结果类型
redirect-action
用于直接跳转到其他Action的结果类型
chain
Action链式处理的结果类型(两个action之间有一定的数据传递关系)
stream
用于向浏览器返回一个InputStream的结果类型
freemarker
用于与FreeMarker整合的结果类型
httpheader
用于控制特殊的HTTP行为的结果类型
velocity
用于整合Velocity的结果类型
xslt
用于整合XML/XSLT的结果类型
15 为什么el表达式能够取得action的属性值 这是为什么呢?
打印request对象的类名,它是struts2提供的一个HttpServletRequest的包装类,这个类重写了getAttribute方法,
这个包装的request对象的getAttribute方法除了找自己的attribute集合,还去ValueStack,
即可以从ValueStack中的各个对象上获取属性。当前的Action又是放在ValueStack的栈顶上的,
所以,在jsp页面中也可以使用${}来获得Action的属性。
查看StrutsRequestWrapper的源码,可以验证上面这个思路。
16 最大的特点的就是脱离的servletAPI
ActionContext每一次执行所产生的数据,也就是依赖的环境
将servletAPI的放在ActionCotext
ActionContext.getContext();返回自己本身
get put --->map request作用域
getSession()-->map session作用
getApplication-->map appliction
getValueStack 值栈
类型转换错误
国际化
使用ThreadLocal模式来解决每次请求的ActionContext是独立的
17 Struts2的结果集类型:
action不配置class的时候,默认的处理类是ActionSupport 默认的处理方法是execute
返回值name默认为success result默认type是dispatcher
18。 struts2如何封装servlet?
在Dispatcher里面调用createContext封装servletAPI,并在里面通过extracContext.put方法,把servletAPI放入actionContext中
通过继承AbstractMap,定义了一个自己的map类,在get方法里面调用了request.getAttribute(key.toString);方法
所以在ActionContext.getContext().get();的时候其实就是调用了request.getAttribute(key.toString);方法
19.requestMap等servletapi如何跟ActionContext挂钩(联系)的?
1、根对象
以下访问要加#号,因为是用map封装的
2、parameters
3、request
4、session
5、application
6、attr,先拿request的值,拿不到时就去拿session的,拿不到session的就去拿application
20.、Ognl表达式
Map map = new HashMap();
map.put("aaa","2222");
Person person = new Person();
person.setName("张三");
拿map中值,Ognl.getValue("#aaa",map,person);
那根里面的值,也就是值栈里面的值.Ognl.getValue("name",map,person);
这就是为什么struts2为什么要把servletAPI封装成map的原因,因为ognl必须这样
21、ActionContext如何保证线程安全?
ThreadLocal
actionContext是放在ThreadLocal里面的,以保证线程安全
新张老师课堂总结:{
Administrator 11:36:20 (多人发送)
actioncontext是被存放在当前线程中的,获取ActionContext也是从ThreadLocal中获取的。所以在执行拦截器、 action和result的过程中,
由于他们都是在一个线程中按照顺序执行的,所以可以可以在任意时候在ThreadLocal中获取 ActionContext。
ActionContext包括了很多信息,比如Session、Application、Request、Locale、ValueStack等,
其中 ValueStack可以解析ognl表达式,来动态去一些值,同时可以给表达式提供对象。值栈是建立在ognl的基础之上的。
Administrator 11:36:27 (多人发送)
1 Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
返回 extraContext 该map信息如下
把 servlet 中paramtert request session application 转换成map,这样struts2就脱离了servlet api
并且 把我们转化后的一个个map放入ActionContext,同时在返回的extraContextke中有paramter,request,session,application,attr
这些key值所对应的value值就是上面的一个个map
还有 一个attr AttributeMap request-sessio-application
}
22. struts1无法验证指定的方法,只能验证form或path,而struts2提供了对指定方法validateXXX方法的验证。但是验证了指定validateXXX方法
后,还是会验证validate方法,那么如果跳过validate方法呢?可以使用注解、零配置做到,对方法进行标记,xml配置时无法做到的
@SkipValidation //配置指定方法跳过验证
@InputConfig(resultName="add") //出现错误跳回<result name="add"></result>的页面
@InputConfig(nethodName="xxx") //指定出现错误跳入那个方法,并根据方法的返回值进入result
public String xxx(){
return "input"
}
使用注解配置拦截器:
@InterceptorRef(value="timer") //配置拦截器timer,执行这个action所需要的时间
拦截器的注解使用,比较使用的
@Before(priority=1)
@After()
令牌机制
token:
<s:token/>
<result name="invalid.token">/add.jsp</result>
<interceptor-ref name="token"></interceptor-ref>
tokenSession:比token好用,不需要指定result并且不会产生<s:actionerror/>信息
<interceptor-ref name="tokenSession"></interceptor-ref>