ognl表达式的部分功能

在这里我们来讨论一下ognl表达式的3个功能:
一、利用ognl表达式创建list/Map对象
二、判断某个对象是否存在于集合中
三、通过一定的规则来获取集合中的子集

/分-------------------------------线-----------------/

一:在El表达式中,我们要弄到一个集合对象的做法是在servlet中创建一个集合,然后给它命名,然后放到某个域对象中,然后在jsp中利用El表达式得到这个集合。
1、但是OGNL可以直接在jsp中创建list。这个要借助标签
代码如下:

    <s:set var="list" value="{'a','b','c'}"></s:set>
    <s:debug></s:debug>

然后访问http://localhost:8080/struts2Day03/ognl.jsp
点开debug后,使用快速查找 list
这里写图片描述

其实标签中还有一个scope属性:就是指存放的范围,翻阅tld文件,看到

  <description><![CDATA[The scope in which to assign the variable. Can be <b>application</b>, <b>session</b>, <b>request</b>, <b>page</b>, or <b>action</b>.]]></description>

可以存在5个范围,默认的是action范围。

获取里面的内容:

    <s:iterator value="#list" var="l">
        <s:property value="#l"/>
    </s:iterator>

2、创建Map

<s:set var="map1" value="#{'a':'valueA','b':'valueB'}" "></s:set><br/>

如果要读取Map中的内容,尽量使用标签,也可以使用El表达式

    <s:iterator value="#map1" var="me">
        <s:property value="#me.key"/>=<s:property value="#me.value"/>
    </s:iterator>

El表达式的形式为:

    <c:forEach items="${map1}" var="me">
        <c:out value="${me.key}=${me.value}"></c:out>
    </c:forEach>
/分-------------------------------线-----------------/

二、判断某个对象是否存在于集合:
借助于标签,代码如下:

    <s:set value="{'aaa','bbb'}" var="list"></s:set>
    <s:if test="'aaa'  in #list">
        yes
    </s:if>

因为ognl表达式还有直接创建list/map的功能所以也可以写成这样:

    <s:if test="'aaa'  in {'aaa','bbb'}">
        yes
    </s:if>

如果存在,就显示标签中的内容,如果不存在就不显示,
除了用In ,还可以用 not in

    <s:if test="'aaa' not in {'aaa','bbb'}">
        不存在
    </s:if>

其实里面的道理,跟Java中的If判断是一个意思,只不过In/not in 在这里被当作关键字

/分-------------------------------线-----------------/

三、通过一定的规则来获取集合中的子集
常用的符号有 ? ^ $
上面3个符号分别代表 符合逻辑的所有元素、符合逻辑的第一个元素、符合逻辑的最后一个元素。

那么我们就拿书本来做例子,本来有3本书,他们的价格不一样,通过价格来筛选出所有符合逻辑的元素

(1)在struts.xml文件配置如下:

<action name="ognlAction2" class="cn.ansel.domain.bookAction" method="showAllBooks">
            <result name="success">/success.jsp</result>
        </action>

(2)根据struts.xml配置文件,创建相关的类,方法,页面

这是book类:

package cn.ansel.domain;

import java.io.Serializable;

public class Book implements Serializable {
    private String name;
    private float price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
    public Book(String name, float price) {
        super();
        this.name = name;
        this.price = price;
    }
    public Book() {
    }

}

然后是action类:

package cn.ansel.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class bookAction extends ActionSupport implements Serializable {
    private List<Book> books;

    public List<Book> getBooks() {
        return books;
    }

    public void setBooks(List<Book> books) {
        this.books = books;
    }


    public String showAllBooks(){
    //这里为了方便,没有写mvc三层架构,就直接new arrayList当作从数据库中取出的内容。
        books=new ArrayList<Book>();
        books.add(new Book("猫生十年", 5.5f));
        books.add(new Book("白夜行", 45.5f));
        books.add(new Book("神秘事件录", 35.5f));
        return SUCCESS;
    }
}

然后是页面:

    <s:iterator value="books.{?#this.price>10.0f}" var="book">
        <s:property value="book.name"/>:<s:property value="book.price"/>
    </s:iterator>

输出的结果是:
这里写图片描述

在上面可以看到,books.{?#this.price>10.0f},其实ognl的筛选功能就出现在.{?#this.price>10.0f}中,用大括号把规则括起来,?代表符合该规则的所有元素,由于这里在迭代,所以要用到当前对象this 当然,关于迭代的标签,为什么要用#this呢,不是说books对象存在于valueStack中吗?那么为什么要用?

这是因为在迭代的时候,books本来是在valueStack中的,但是在被迭代到的过程中,当前对象就会被弹栈,就存在于actionContext中了,所以要指明名称空间。

this代表当前对象,this.price代表当前的对象的price属性,这样来理解就明了了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值