Struts2重要的类和接口总结回顾
1.0.1 ActionContext
ActionContext是线程安全的 因为ActionContext的实例是在ThreadLocal中的
static ThreadLocal actionContext=new ThreadLocal();
Struts2的Action上下文。可以获得Action的上下文 getContext() 可以获得值栈,Session 等
Struts2对HttpServletRequest ,HttpSession 和SerletContext 进行了封装,构造了三个Map对象
1.0.2 ServletActionContext
:主要建立Struts2与Servlet的通信桥梁
1.0.3 ActionInvocation 他是一个接口
: 提供了Struts2容器总的上下文控制Interceptors,Action,Result 整体的执行过程
getAction() 可以获取Action
可以通过getInvocationContext()获得ActionContext();
getProxy()可以获得代理,通过Proxy也可以获得所有的拦截器
getProxy.getConfig().getInterceptors();
getResult()可以获得结果集
getStack()可以获得值栈
----DefaultActionInvocation表示ActionInvocation的实现类
1.0.4 ActionProxy
是执行框架的入口,可以 他是Interceptors,Action,Result等的的入口,主要完成ActionInvocation的初始化和调用
//获得所有的拦截器
ActionContext.getContext().getActionInvocation().getConfig().getInterceptors();
1.0.5 ObjectFactory
ObjectFactory是struts2的对象工厂,所有的Action,结果集,拦截器,验证器,bean都从 objcetFactory中产生的
如果spring与struts2整合的时候,需要把对象的产生交给spring产生,因此需要继承objectFactory类
如何配置ObjectFactory
机制 : 静态注入,一般配置的bean都是静态注入,因此这些东西都可以进行自定义的配置设置
配置: 在struts-plugin文件中 重写配置该bean
<bean type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory" />
1.0.6 defautActionInvocation的execute执行过程是:
1.先执行所有的拦截器
2.然后执行目标类的目标方法
3.最后调用结果集的结果方法
Struts2 数据的存放-ValueStack
Struts2的数据都是在值栈中,怎么保证数据的安全性,值栈的生命周期是
ValuesStack在ActionContext中,但是ActionContext在ThreadLocal中
值栈存在于Request中,所以值栈的生命周期是一次请求,而且ACtion中,当前的Action,actionContext ,valuestack的生命周期是一致的
ValueStack 其实就是一个接口, 实现他的类是onglValeStack
ognl对象图形化导航语言object-Graph Navigation Language
ValueStack 对象保存在名为 “strtuts.valueStack”的请求属性中,request
获得ValueStack的方式有如下:
方式一
HttpServletRequest request = ServletActionContext.getRequest();
ValueStack valueStack1 = (ValueStack) request.getAttribute("struts.valueStack");
方式二
ValueStack valueStack2= ServletActionContext.getContext().getValueStack();
valueStack2.set("error", "ssss"); //先产生Map 然后添加到Map中,最后添加到对象栈中
valueStack2.set("msg", "zhongguo");
valueStack2.getRoot().add(new Person());直接压入对象栈中
OgnlValueStack中有两个属性
1.CompoundRoot root;
ComponundRoot extends ArrayList 因此 root 就是一个List 的集合 表示对象栈
ValueStackAction 对象栈
Map集合
业务(Student,Person等)对象
其他对象
2. transient Map<String,Object> context;
OgnlContext extends Object implements Map
主要存放session,Application,request 同时需要把root拷贝一份放进去
request.getParameter("name"); 表示获取表单中的值
request.getAttribute("name");表示获取自己存储的值
Struts2 的流程
简单概括:
Struts2最核心的原理是AOP动态代理,我觉得可以把所有的拦截器都可以看做是切面,把拦截器中的方法看做是通知。我们编写的ACtion 仅仅是目标类的目标方法
spring容器 要进行对Action的管理必须实现Struts2 的OjectFactory,
这里可以通过Struts-plugin.xml 文件可以覆盖相同的东西
需要考虑两部分
1.0 tomcat启动的时候
init()方法初始化:
加载默认的配置文件 init_DefaultProperties 加载了default.properties配置文件
加载传统的配置文件的顺序是:
struts-Default.xml, 只有一个
struts-plugin.xml, 可能有多个个
struts.xml; 只有一个
注意:
struts-plugin会有多个,如果内容一样,后者覆盖前者。
struts2容器会在classpath的环境下,夹jar包下查找所有的struts-plugin
静态注入注入 标注了bean的类
init.initStaticContentLoader(config,dispatcher);
1.1 当请求一个url的时候
首先创建ActtionContext放入到了LocalThread中
然后把ValueStack放入到ActionContext
值栈的创建优先于Action的创建
Strtus2自定义结果集
基础回忆:
type 默认的情况下是转发-dispatcher,当然还有重定向(redirect),错误页面(input),ch重定向到Action(redirectAction)
Result 一般格式是:
<result name="SUCCESS">/jsp/hello.jsp</result>
Result 标准格式是:
<result name="fail" type="dispatcher">
<param name="location">/jsp/fail.jsp</param>
</result>
param 是参数
name 参数的名字是location 注意这里的参数名称是不会改变的他的实质是StrutsResultSupport类的setlocation方法通过注入进去的`
所谓的参数,是get或者set方法所跟的名称,
重定向到Action
<result name="fail" type="redirectAction">
<!-- actionName 指定struts标签name属性的值 -->
<!-- namespace 指定命名空间 -->
<!-- 无论是重定向到jsp还是重定向到action中,底层的代码都是一样的 -->
<param name="actionName"></param>
<param name="namespace"></param>
</result>
获得请求的 result的中间值:
conditionalParse(String location,ActionInvocation invocation) ;
location 就是Result 的中间的值,对location 解析就可以获取想要的值
StrutsResultSuport 抽象类继承了Result 接口,
StrutsResultSupport
void execute
获得result标签的文本值,该方法是一个公用的方法
--lastFinalLocation=conditionalParse(location,invocation);
该方法是抽象方法,自定义结果集的类必须实现该方法
---doExecute(lastFinalLocation,invocation)
StrutsResultSuport特点:因为不是具体的结果集,所以不希望创建对象,
有很多自定义的结果集需要获取result 标签中的文本值,所以该类有个通用的方法,已经把这个功能实现了conditionalParse()
因为各个不同的结果集类型尤其不同的实现逻辑,所以该类中有一个抽象方法,让子类实现
struts2 拦截器不能设置全局拦截器,最多只能跟包
注意struts2的包注意要继承extends="struts-default" ,这也是能够进入struts2机制的一种
Struts2:Action
基础:
Struts2是中的Action 是一个多实例的
线程安全
防止单线程的阻塞
${pageContext.request.contextPath}的作用就是取出部署的应用程序名。这是EL表达式的写法
<%=pageContext.getContextPath()%> jsp的方式获得应用程序名
编写自己的Action 继承自ActionSupport
Action的搜索顺序
--/jsp/zdc/hellow.action;
-- /jsp/zdc/ 首先查找 该包下查找hellow.action如果没有哦找到,去下一个包下去找
--/jsp/ 如果此包没有找到,就会报错
常用文件的作用介绍:
default.properties 文件中配置的使一些常量,这里是系统默认的常量配置文件
-- struts.action.extension=action,, //设置请求路径的扩展名,可以有多个扩展名,默认的是action或者是空
struts.properties 在src 的文件下创建配置该文件,自己配置的常量文件
struts.action.extension=go 表示 以后缀名为go的请求
struts.xml文件中,Struts2项目中的主入口文件
如果同时在struts.properties 和 struts.xml 同时配置一些常量,那么struts.properties 起作用
xwork-conversion.properties:类型转换文件,可以自定义转换类型的类
常用的格式:
java.util.Date=cn.itcast.converter.DateConverter
因为常量可以在多个配置文件中定义,
1.struts-default.xml
2.struts-plugin.xml
3.struts.xml
4.struts.properties(自己创建的在src目录下面)
5.web.xml
通配符的使用
基础回忆:
{1} : 匹配的是“*”通配符的第一个子串
{0} : 匹配的是“*”通配符的整个串
! : 动态方法调用
动态方法调用格式: 页面请求连接 namespace+actionName+"!"+执行方法的
在struts.xml 文件中,不用配置method 属性,而已通过页面的连接动态执行指定方法
默认的情况下动态方法调用时出于激活状态的,如果想要禁用的话,需要自己在Struts.xml 文件中去设置
<!-- <a href="${pageContext.request.contextPath }/jsp/HelloActon!hello.action"></a> --> 表示的动态方法的调用
类型转换:
基础回忆:
在Struts2框架中,在对应动作类action中,声明与页面表单元素同名的属性,给出对应的set get 方法 ,Struts 会根据 反射机制,获取页面中表单元素的值。
类型转换类别: 基于属性,基于类
--属性类型转换
日期类型的转换:
<input name="birthday" />
private Date birthday;
日期类型转化不成
错误提示: No result defined for action XXX and result input
解决方案:
需要自己定制类型转换器
实现TypeConverter接口或者对这个接口的某种具体实现做扩展(
实现TypeConverter 或者实现DefaultType ,StrutsTypeConvert
)
DefaultTypeConvert
convertValue()
解决步骤:
1.创建DateConvert extends DefaultTypeConvert{
public object convertValue(Object vlaue,Class toType)
{
进行类型转换
}
}
2. 在需要进行日志转化的目标类的包下创建properties 文件
Properties文件的名字是 ActtionName-convertsion.properties
内容
3. Action中需要转换的属性=自定义转换类的全名称
如果输入错误的类型,Struts 没有抛出异常 原因: 在Struts2框架里,自定义的类型转化器,如果我们不手动抛出异常,Struts框架只会捕获异常,但是并不会抛出异常,所以类型转换器就会站产成功了
Struts.xml 解析
1.0- constant可以配置常量,也就是说配置存在default.properties 资源文件中的常量
eg:
配置strut2中 页面中请求链接的后缀名,如果value 中有多个值得话用逗号隔开
<constant name="struts.action.extension" value="do"></constant>
配置struts2框架的模式
默认的是
false ,是生产模式
true 是开发模式 需要更多调试细信息
当为true的时候 struts.i18n.reload 和strutsconfiguration.xml.reload将会默认为true
<constant name="struts.devMode" value="true"></constant>
配置动态方法调用为false
struts.enable.DynamicMethodInvocation = true
<constant name="struts.enable.DynamicMethodInvocation" value="false"></constant>
1.1-配置全局结果类型
如果既有全局的结果类型又有局部的结果类型,那么就会执行局部的结果类型 -->
<global-results>
<result name="success">/pattern/a.jsp</result>
</global-results>
1.2-package下容易忽略的两个属性
extends:继承的内容。 通过包之间的继承可以实现 不同包
abstract: 表示该包的下面不能够定义Action的标签
namespace : 命名空间 ,必须是唯一的 可选项 省略的情况下是"/" 页面中请求连接的前半部分
<package name="jsp" namespace="/jsp" extends="struts-default" >
1.3-如果找不到对应的action名称的话,就会执行此默认的 ,可以 进行转向失败页面 或者是主页
<default-action-ref name="default404.jsp"></default-action-ref>