美文网首页
Struts2干货笔记——第四天

Struts2干货笔记——第四天

作者: 深海鱼Q | 来源:发表于2017-06-06 09:59 被阅读0次

    目录

    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.

    相关文章

      网友评论

          本文标题:Struts2干货笔记——第四天

          本文链接:https://www.haomeiwen.com/subject/wstyfxtx.html