java EE开发之Struts2第三章:数据传递(2)

  上一节我们详细讲了jsp页面传递参数到action的整个流程,以及struts2内部的实现方式。这一节我们开始讲解,struts2中action将数据传递给jsp进行回显的内容。

一,struts2是通过什么将数据传递到jsp页面的

  要学会怎么样将数据带到jsp页面进行回显,首先我们得搞清楚struts2是通过什么将数据带过去的,再讲清楚这个问题之前,我们想想我们前面servlet的时候,如果要将数据从servlet带到jsp显示,无非就是通过四大域对象来实现的,servlet将数据保存到四大域对象中,jsp通过el表达式或者jstl标签到四大域中获取值。
  struts2对servlet进行了封装,struts2是内部也有一个数据结构或者说类似四大域对象的一个容器,叫值栈。struts2就是通过他来实现数据的传递的,当然有同学可能会说,难道通过四大域对象不可以吗?当然是可以的,只不过struts2将数据的传递的过程进行了封装,保存到了一个自己开发的数据结构中,为了提高开发速度,毕竟数据的回显,也不是什么很高技术活,但是开发过程中,又有大量的数据回显要去做,所以struts2干脆自己定义一个数据结构:值栈,封装了数据的传递的过程。

二,什么是值栈,值栈的结构是什么样的?

  ValueStack它是一个接口com.opensymphony.xwork2.util.ValueStack。我们使用它是将其做为一个容器,用于携带action数据到页面,在在页面上通过ognl表达式获取数据。
valueStack主要是将action数据携带到页面上,通过ognl获取数据
1,ValueStack有一个实现类叫OgnlValueStack.
2,每一个action都有一个ValueStack.(一个请求,一个request,一个action, 一 个valueStack) valueStack生命周期就是request生命周期。
3,ValueStack中存储了当前action对象以及其它常用web对象
(request,session,application.parameters)
4,struts2框架将ValueStack以“struts.valueStack”为名存储到request域
中。

值栈的结构
  在aciton中通过下面的代码得到值栈—进行debug查看 结构
ValueStack vs=(ValueStack)ServletActionContext.getRequest().
这里写图片描述

通过调试得到下面的结论:
ValueStack中存在root属性(CompoundRoot),context属性(OgnlContext)

CompoundRoot 就是ArrayList
OgnlContext 就是 Map

list集合中存储的是action相关信息。
map集合中存储的是相关映射信息,包含
Paramters:该map中包含当前请求参数
Request:该map中包含当前request对象中的所有属性
session:该map中包含当前session对象中的所有属性
application:该map中包含当前application对象中的所有属性
Attr::该map按如下顺序来检索某个属性:request seesion,application

我们想要从list中获取数据,可以不使用#号.(它就是ognl的root)
如果从map中获取数据,需要使用#. (其实在struts2中的map–>context 其实就是 ognlContext–看源码OgnlValueStack 源码)

三,OGNL表达式

1,OGNL表达式是什么?

  OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

xwork 提供 OGNL表达式
ognl-3.0.5.jar

OGNL 是一种比EL 强大很多倍的语言

OGNL 提供五大类功能
1、支持对象方法调用,如xxx.doSomeSpecial();
2、支持类静态的方法调用和值访问
3、访问OGNL上下文(OGNL context)和ActionContext; (重点 操作ValueStack值栈 )
4、支持赋值操作和表达式串联
5、操作集合对象。

2,ognl表达式访问对象方法和静态方法

  OGNL 在jsp 结合 struts2 标签库 使用 :

<s:property value="ognl表达式" />

执行ognl表达式
调用 实例方法 : 对象.方法()

<s:property value="'hello,world'.length()"/>

调用 静态方法 : @[类全名(包括包路径)]@[方法名]

 <s:property value="@java.lang.String@format('您好,%s','二娃子')"/>

使用 静态方法调用 必须 设置 struts.ognl.allowStaticMethodAccess=true

3,jsp中获取值栈的数据

root中数据不需要#,而context中数据需要#
1.如果栈顶是一个Map集合,获取时,可以直接通过Map集合的key来获取value.

<s:property  value="username"/>

2.如果栈顶数据不是一个Map,没有key值,可以使用序号来获取。

<s:property value="[0]">  从0的位置向下查找所有。
<s:property value="[1]">  从1的位置向下查找所有。
<s:property value="[0].top"> 只查找0位置上数据。

如果获取OgnlContext中数据:这里的web对象是struts包装后的web对象

1.request数据 request.setAttribute()
2.session数据 session.setAttribute()
3.application数据 application.setAttribute()
4.attr 依次从request,session.application中查找
5.parameters 获取请求参数(表单,超链接)

那么在Jsp页面中可以通过下面的代码获取OgnlContext中数据:

<s:property  value=”#request.rname”/>
<s:property  value=”#session.sname”/>
<s:property  value=”#application.aname”/>
<s:property  value=”#attr.rname”/>
<s:property  value=”#parameters.username”/>

四,值栈在开发中的使用

  主流应用 : 值栈 解决 Action 向 JSP 传递 数据问题 ,Action 向JSP 传递数据处理结果 ,结果数据有两种形式
1) 消息 String类型数据

this.addFieldError("msg", "字段错误信息");
this.addActionError("Action全局错误信息");
this.addActionMessage("Action的消息信息");
  • fieldError 针对某一个字段错误信息 (常用于表单校验)、actionError (普通错误信息,不针对某一个字段 登陆失败)、 actionMessage 通用消息

在jsp中使用 struts2提供标签 显示消息信息

<s:fielderror fieldName="msg"/>
<s:actionerror/>
<s:actionmessage/>

2) 数据 (复杂类型数据)
使用值栈 valueStack.push(products);此方法就是值栈内部将数据放入值栈根部的方法。

哪些数据默认会放入到值栈 ???

1)每次请求,访问Action对象会被压入值栈 ——- DefaultActionInvocation 的 init方法 stack.push(action);Action如果想传递数据给 JSP,只有将数据保存到成员变量,并且提供get方法就可以了
2)ModelDriven 接口 有一个单独拦截器

<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>

在拦截器中 ,将model对象 压入了 值栈 stack.push(model); 如果Action 实现ModelDriven接口,值栈默认栈顶对象 就是model对象

总结: url访问action—>将action压入值栈—>ModelDriver拦截器将 getModel返回值压 入值栈—->action中将getXX方法以xx为键,以返回值为值压入值栈中

五,OGNL表达式特殊符号使用

1) # 的 使用
用法一 # 代表 ActionContext.getContext() 上下文

 <s:property value="#request.name" />  

以上代码等价于 ActionContext().getContext().getRequest().get("name");
#request
#session
#application
#attr
#parameters 类似不再举例。

用法二 : 不写# 默认在 值栈中root中进行查找
<s:property value="name" /> 在root中查找name属性,查询元素时,从root的栈顶元素 开始查找, 如果访问指定栈中元素 <s:property value="[1].name" /> 访问栈中第二个元素name属性
访问第二个元素对象 <s:property value="[1].top" />

用法三 :进行投影映射 (结合复杂对象遍历 )
1)集合的投影(只输出部分属性,如:遍历集合只要name属性)

<s:iterator value="products.{name}" var="pname"> 
    <s:property value="#pname"/>
</s:iterator>

2)遍历时,对数据设置条件 如:遍历集合只要price大于1500商品

<s:iterator value="products.{?#this.price>1500}" var="product"> 
        <s:property value="#product.name"/> --- <s:property value="#product.price"/>    
    </s:iterator>

3)综合 如:只显示价格大于1500 商品名称

<s:iterator value="products.{?#this.price>1500}.{name}" var="pname">         
    <s:property value="#pname"/>
</s:iterator>

用法四: 使用#构造map集合
经常结合 struts2 标签用来生成 select、checkbox、radio
如:使用#构造map集合 遍历

<s:iterator value="#{'name':'aaa','age':'20', 'hobby':'sport' }"var="entry">
    key : <s:property value="#entry.key"/> ,
    value:  <s:property value="#entry.value"/> <br/>
</s:iterator>

2)%的使用
%作用:就是用于设定当前是否要解析其为 ognl表达式.

%{表达式} 当前表达式会被做为ognl解析.
%{‘表达式’} 当前表达式不会被做为ognl解析。

用法一: 结合struts2 表单表单使用, 通过%通知struts, %{}中内容是一个OGNL表达式,进行解析

   <s:textfield name="username" value="%{#request.username}"/>

用法二: 设置ognl表达式不解析 %{‘ognl表达式’}

<s:property value="%{'#request.username'}"/>

3)$的使用

用法一 :用于在国际化资源文件中,引用OGNL表达式
在properties文件 msg=欢迎您, ${#request.username}
在页面

<s:i18n name="messages">
    <s:text name="msg"></s:text>
</s:i18n>

自动将值栈的username 结合国际化配置信息显示

用法二:在校验文件中使用

${min} 			${max}
${minLength} 	${maxLength}

用法三:在Struts 2配置文件中,引用OGNL表达式

<!-- 在Action 提供 getContentType方法 -->
struts.xml
<result type="stream">
    <param name="contentType">${contentType}</param>
</result>       

${contentType} 读取值栈中contentType数据,在Action提供 getContentType 因
为Action对象会被压入值栈,contentType是Action属性,从值栈获得
结论: #使用ognl表达式获取数据,% 控制ognl表达式是否解析 。
$用于配置文件获取值栈的数据

·

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值