Struts2与JSP间数据到底怎么传输的?

本文探讨了Struts2中数据如何从Action传递到JSP页面,核心机制是ValueStack。Action对象被放入ValueStack,接着ValueStack通过request域传递到JSP,使得JSP能用OGNL表达式访问数据。ValueStack、ActionContext和OgnlContext之间的关系也得到了解析,解释了两种不同的取值方式。

初学Struts2,遇到在Jsp页面上使用类似<s:property value="user.name"/>语句,心中一万个疑惑“这竟然可以读取到在之前在action里创建的(有setter和getter)变量(user)?”how can that be???

好的,带着这份疑惑,我决定好好研究一下这个东东。

数据传输背后机制就是 ValueStack(值栈)。


ValueStack简介

Valuestack存储的内容:
这里写图片描述

  1. 当用户访问Action,都会创建一个Action对象,ActionContext对象、valueStack对象..
  2. Struts2把Action对象放进valueStack对象之中。
  3. 将valueStack放进request域中,传入JSP页面(key: struts.valueStack)
  4. JSP页面就可以使用OGNL表达式获取值栈中的数据了!

在debug模式下,看看valuestack里面有哪些东西:
这里写图片描述
其中OgnlContext就是一个Map集合。

OgnlContext保存着这样的数据:

  • 维护了CompoundRoot中所有的数据
  • request、response等域对象所有的数据

CompoundRoot里面:
这里写图片描述
终于,我们看到了LoginAction,里面自定义的全局变量user和message也都保存了下来,还有保存error相关的变量。

CompoundRoot保存着这样的数据:

  • Action对象以及Action对象的成员属性数据
  • 使用ValueStack对象.push()进去的数据
  • 使用ValueStack对象.set()进去的数据
  • 其他代理对象的数据。

有个问题:Actioncontext和Onglcontext、OnglValueStack间有什么关系?
这里写图片描述
这图很有意思,我们可以得出以下结论:
1. ActionContext 里面就是 OnglContext;
2. OnglValueStack里面保存了OnglContext;
3. OnglContext里面保存了OnglValueStack(引用),有种循环的感觉。
4. OnglValueStack里面也保存了request。
再看一幅图:
这里写图片描述
request里面也有OnglValueStack。。。

完美诠释了“你中有我,我中有你…”

这也解释了为什么以下两种取值栈方式都可行了:

// 获取值栈对象,方式1:
HttpServletRequest request = ServletActionContext.getRequest();
ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack");

// 获取值栈对象,方式2: 
ActionContext ac = ActionContext.getContext();
ValueStack vs2 = ac.getValueStack();

ongl取值

Struts2会将valueStack对象封装进request对象域中,传入JSP页面。
取值规则:
这里写图片描述
(来自:https://www.jianshu.com/p/eb190a6ecc6b

  • 如果是CompoundRoot类的数据(根元素),表达式不需要带#号(主要是action里面数据以及push进的数据)
  • 如果不是CompoundRoot类的数据,表达式需要带#号(客户端传来的参数parameter,session内容等)

其他:

<body>
     <br/>获取request域数据<br/>
     <!-- property 标签是对象类型的标签,默认支持ognl表达式, 会从根元素去China名称对应的值 -->
     <s:property value="China"/>        <br/>
     <!-- 如果直接赋值,需要用单引号 -->
     <s:property value="'China'"/>      <br/>
     <s:property value="%{#request.cn}"/>       <br/>

     <!-- 值类型的标签,value值默认就是值类型,不支持ognl表达式 -->
     国家:<s:textfield name="txtCountry" value="%{#request.cn}"></s:textfield>
  </body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值