struts2值栈深入理解

struts2值栈

值栈(ValueStack)是struts2中的一个重要的概念,几乎所有的Struts2操作都要同值栈打交道。那么值栈究竟是什么呢?

实际上struts2中的值栈就是一个存放对象的堆栈,对象以map的形式存储在这个堆栈中,并且该堆栈中的对象属性的数值可以通过表达式语言获得。

    Struts 2Action类通过属性可以获得所有相关的值,如请求参数、Action配置参数、向其他Action传递属性值(通过chain结果)等等。要获得这些参数值,我们要做的唯一一件事就是在Action类中声明与参数同名的属性,在Struts 2用Action类的Action方法(默认是execute方法)之前,就会为相应的Action属性赋值。 

  要完成这个功能,有很大程度上,Struts 2要依赖于ValueStack对象。这个对象贯穿整个Action的生命周期(每个Action类的对象实例会拥有一个ValueStack对象)。当Struts 2接收到一个.action的请求后,会先建立Action类的对象实例,但并不会调用Action方法,而是先将Action类的相应属性放到ValueStack对象的顶层节点(ValueStack对象相当于一个栈)。只是所有的属性值都是默认的值,如String类型的属性值为null,int类型的属性值为0等。 

  在处理完上述工作后,Struts 2就会调用拦截器链中的拦截器,当调用完所有的拦截器后,最后会调用Action类的Action方法,在调用Action方法之前,会将ValueStack对象顶层节点中的属性值赋给Action类中相应的属性。大家要注意,在这里就给我们带来了很大的灵活性。也就是说,在Struts 2调用拦截器的过程中,可以改变ValueStack对象中属性的值,当改变某个属性值后,Action类的相应属性值就会变成在拦截器中最后改变该属性的这个值。 

  从上面的描述得出,在Struts 2的的Action类可以获得与属性同名的参数值就是通过不同的拦截器来处理的,如获得请求参数的拦截器是params,获得Action的配置参数的拦截器是staticParams等。在这些拦截器内部读取相应的值,并更新ValueStack对象顶层节点的相应属性的值。而ValueStack对象就象一个传送带,将属性值从一个拦截器传到了另一个拦截器(当然,在这其间,属性值可能改变),最后会传到Action对象,并将ValueStack对象中的属性的值终值赋给Action类的相应属性。

 

     在struts 2框架中,任何Action所涉及到的数据都要被存入Action上下文,同时在值栈中也会创建一个这些数据信息的副本。可以这样形象的比喻:这时候的值栈就相当于一个“仓库”,数据信息到来时装入“仓库”,需要时可以从“仓库”中取出这些数据信息。

值栈ValueStack是Struts2框架核心组件,它提供对上下文信息和执行环境中元素的访问机制。其在底层实现了一个栈,但与传统栈的实现有所不同。

值栈由以下4个层级对象组成
(1) 临时对象:这些对象在请求处理过程中需要临时保存,比如集合中当前正在迭代的元素;
(2) 模型对象:当Action实现了ModelDriven接口时,模型对象就会被存放在栈中被执行的Action前面;否则不存在这个级别的内容。
(3) Action对象:此对象为当前正在执行的action。
(4) 命名对象:任何对象都可以被赋予一个标志符而成为命名对象。比如与HTTP同等作用域的对象集合对应的Struts2命名对象,#application、#session、#request、#attr和#parameters等。
值栈的使用方式
栈的传统使用方式是压栈和出栈。对于值栈则是通过使用OGNL
(Object Graph Navigational Language对象导航语言)语法编写的特定表达式来查找,或者是在该表达式之上求值。

OGNL表达式
使用圆点符号和表达式求值
调用被检索对象的方法
结合自定义标签使用
常见用法:
(1) person.name   调用getPerson().getName()
(2) #session.user 从会话对象中获取user属性对象
(3) #session.shopcart.size() 获取会话中购物车的数量
(4) top 获取值栈最顶层对象
类型转换:
Struts2内置的类型转换:
String和int、Integer
String和double、Double
String和Map、List
String和Date
String和boolean
String和char
Struts2自定义类型转换
在Struts2中提供了StrutsTypeConverter类来简化自定义类型转换的设计,这个类有两个抽象方法需要实现:

(1) public Object convertFromString(Map context, String[] values, Class toClass) ;
          用于String类型数据转成自定义类型的处理方法参数:
             context --- 与Action有关的上下文信息
             values   --- 从请求中获取的参数值
             toClass --- 要转换的目标类型
public String convertToString(Map context, Object obj) ;
    用于自定义类型转换成String
      参数:
         context --- 与Action有关的上下文信息
         obj --- 自定义类型对象
多说不如多做,下面看具体的小应用:
注册页面的写法:
<input type=”text”name=”username”>
<input type=”password”name=”password>”
<input type=”submit” value=”提交”/>
Action组件中:
Public UserAction extends ActionSupport
{
private String username;
private String password;
//别忘了给username和 password提供set()和get()方法
System.println.out(“用户名”+username);
System.println.out(“密码”+password);

}
相对应---------username—password,在页面中的空间名字和action中的变量名;

 

你在Interceptor中是看不到你期望的判断语句的。因为,封装的判断语句在Servlet的容器中实现;解封装的语句,在struts2的OGNL中实现。Interceptor只是对其中值,稍微做些处理 

 

http://pengfeicao521.iteye.com/blog/337893


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值