Struts2干货笔记——第四天

目录

1. OGNL表达式的使用和值栈ValueStack
  • 1.1 OGNL的简介
  • 1.2 在struts2中使用ognl表达式
  • 1.3 ValueStack值栈简介
  • 1.4 ValueStack的理解
  • 1.5 ValueStack对象的创建过程
  • 1.6 获得值栈对象
  • 1.7 向ValueStack中的root中保存数据
  • 1.8 在JSP页面中获取值栈的数据
  • 1.9 OGNL表达式常见使用($ % #)

OGNL表达式的使用和值栈ValueStack

OGNL的简介

OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言, Struts2框架使用OGNL作为默认的表达式语言。

OGN相对于其他表达式语言具有的优势:

  1. 支持对象方法调用,例如xxx.run()
  2. 支持类静态方法的调用和值访问
  3. 访问OGNL上下文(OGNL context)和ActionContext
  4. 支持赋值操作和表达式串联
  5. 操作集合对象
在struts2中使用ognl表达式

使用ognl表达式需要结合struts2的标签<s:property value="ognl表达式">
@[类全名(包括包路径)]@[方法名或者值名]

<s:property value="'abc'.length()"/>  演示对象调用方法
<s:property value="@java.lang.Math@max(10,20)"/> 演示静态成员访问.

注意:在struts2中使用静态成员访问,必须设置一个常量:struts.ognl.allowStaticMethodAccess=false 在struts.xml中改为true

ValueStack值栈简介

它是一个接口com.opensymphony.xwork2.util.ValueStack。我们使用它是将其做为一个容器,用于携带action数据到页面,再在页面上通过ognl表达式获取数据。

  1. ValueStack有一个实现类叫OgnlValueStack.
  2. ValueStack贯穿整个Action的生命周期,每一个action都有一个ValueStack,相当于一个数据的中转站(一个请求,一个request,一个action,一个valueStack) valueStack生命周期就是request生命周期。
  3. valueStack中存储了当前action对象以及其它常用web对象(request,session,application.parameters)
  4. struts2框架将valueStack以“struts.valueStack”为名存储到request域中。
ValueStack的理解

ValueStack中存在root属性 (CompoundRoot) 、context 属性 (OgnlContext ),其中root本质上是一个ArrayList,而context是一个Map。而在这个OgnlContext对象(context)中有一个默认的顶层对象root。OGNL访问context中这个默认顶层对象中的元素时不需要加#号,直接通过元素名称来进行访问,而在访问其他对象时,需要加#号。list集合中存储的是action相关信息map集合中存储的是相关映射信息,包含paramters,request,session,application,attr等。


OgnlContext.png
ValueStack对象的创建过程

值栈对象在每一次请求时都会创建,在ActionContext中持有了valueStack的引用。

ActionContext ctx = ActionContext.getContext();
    if (ctx != null) {
          stack = ctx.getValueStack();
    }
获得值栈对象
  1. 通过 request获取
ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
  1. 通过ActionContext获取
ValueStack ValueStack =ActionContext.getContext().getValueStack();

向ValueStack中的root中保存数据

  1. push(Object obj) 方法讲数据保存在root的索引0位置,将数据储存到栈顶
ValueStack .push("abc");
  1. set(String name,Object obj)方法在值栈创建map,将数据保存到map中
ValueStack.set("username","tom");

在JSP页面中获取值栈的数据

访问root中数据不需要#,而其他对象需要#

  1. 如果栈顶是一个Map集合,获取时,可以直接通过Map集合的key来获取value.
    <s:property value="username"/>
  2. 如果栈顶数据不是一个Map,没有key值,可以使用序号来获取。
    <s:property value="[0]"> 从0的位置向下查找所有。
    <s:property value="[0].top"> 只查找0位置上数据。

在OgnlContext中获取数据
request:<s:property value="#request.username"/>
session:<s:property value="#session.username"/>
application:<s:property value="#application.username"/>
attr:<s:property value="#attr.username"/>
parameters:<s:property value="#parameters.cid[0]"/>

OGNL表达式常见使用($ % #)

** #的用法**
用法一:访问OGNL上下文和Action上下文,#相当于ActionContext.getContext()

  1. 如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#
    <s:property value="#request.name"/>相当于
    ActionContext().getContext().getRequest().get("name");
  2. ognl会设定一个根对象(root),在Struts2中根对象就是ValueStack(值栈),如果要访问根对象(即ValueStack)中的属性,则可以省略#,直接访问该对象属性。
Action代码
ValueStack valueStack=ServletActionContext.getContext().getValueStack();
valueStack.set("username","username_valueStack"); 
JSP页面
valueStack: <s:property value="username" />

用法二:集合的投影

  1. 只输出部分属性
<h1>遍历集合只要name属性</h1>
<s:iterator value="products.{name}" var="pname"> 
    <s:property value="#pname"/>
</s:iterator>
  1. 遍历时,对数据设置条件
<h1>遍历集合只要price大于1500商品</h1>
<s:iterator value="products.{?#this.price>1500}" var="product">
<s:property value="#product.name"/> --- <s:property value="#product.price"/>    
</s:iterator>
  1. 综合
<h1>只显示价格大于1500 商品名称</h1>
<s:iterator value="products.{?#this.price>1500}.{name}" var="pname"> 
<s:property value="#pname"/>
</s:iterator>   

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

<h1>使用#构造map集合 遍历</h1>
<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>

** %的用法**
用于设定当前是否要解析其为 ognl表达式.
%{表达式} 当前表达式会被做为ognl解析.
%{'表达式'} 当前表达式不会被做为ognl解析。
<s:property value="表达式"> 对于s:property标签,它的value属性会被默认做为ognl.

在JSP页面
<s:textfield name="name" label="%{#request.username}">

** $的用法 **
配置文件中使用ognl表达式来获取valueStack中数据

  1. 在国际化资源文件中引用OGNL表达式
    Action中的代码:
    ServletActionContext.getRequest().setAttribute("msgxx", "msg_request");
    在com.java.ognl中建立资源文件resource.properties,内容:
    item.ognlname=${#request.msgxxx}
    ognl.jsp文件中
    <s:i18n name="com.java.ognl.resource">
    <s:text name="item.ognlname"></s:text>
    </s:i18n>
    运行结果是
    msg_request

  2. 在struts2配置文件中引用OGNL表达式,引用request等作用域中的值
    Action中的代码:
    ServletActionContext.getRequest().setAttribute("msgxx", "msg_request");
    struts.xml文件中
    <package name="ognl" namespace="/ognl" extends="struts-default" >
    <action name="ognlAction_*" class="cn.itcast.ognl.OgnlAction" method="{1}">
    <result name="ognl">/ognl/ongl.jsp?msg=${#request.msgxx}</result>
    </action>
    </package>
    jsp页面:
    parameters Msg:<s:property value="#parameters.msg[0]"/>
    运行结果是
    msg_request

总结: #就是用于获取数据 %就是用于设置是否是ognl表达式 $就是在配置文件中使用ognl.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容