6.OGNL表达式(struts2笔记)

OGNL是一种表达式语言,可以存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。(工程Struts2_1900_OGNL)。
这里需要做的试验较多,我们一个一个讲解。

1.访问值栈中的action的普通属性

ognl.jsp

<li>1.访问值栈中的action的普通属性: username = <s:property value="username"/> </li>

OgnlAction.java

    //试验1-------
    private String username;
    private String password;
    //试验1-------
    
    public String execute(){
        return SUCCESS;
    }

说明:这里的action中我们只有两个属性,我们通过OGNL表达式value="username"可以直接从值栈中取得属性的值。我们可以在值栈中找到对应属性的值。

2.访问值栈中对象的普通属性

ognl.jsp

<li>2.访问值栈中对象的普通属性(get set方法):<s:property value="user.age"/> | <s:property value="user['age']"/> | <s:property value="user[\"age\"]"/> | wrong: <%--<s:property value="user[age]"/>--%></li>

OgnlAction.java

    //试验2-------
    private User user ;
    //试验2-------

User.java

package com.bjsxt.struts2.ognl;
public class User {
    private int age = 8;

    public User(){}
    
    public User(int age) {
        super();
        this.age = age;
    }

    @Override
    public String toString() {
        return "user" + age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

说明:

  • 当我们使用地址http://localhost:8080/Struts2_1900_OGNL/ognl.action?username=u&password=p访问时我们在值栈中发现user对象是null,之前我们知道struts2会帮我们实例化对象,但是这必须有个条件,就是地址后面必须跟上相应的值,如:
    http://localhost:8080/Struts2_1900_OGNL/ognl.action?username=u&password=p&user.age=10这时struts2才会帮我们实例化对象,同时我们的对象中必须有无参构造函数,因为struts2在实例化时需要用到。当然我们也可以自己在action方法中直接将user对象new出来,这相当于自己实例化对象了。
  • 这里我们给出了几种取得普通属性的OGNL表达式,注意其区别。

ognl.jsp

<li>3.访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name"/></li>

OgnlAction.java

    //试验3-------
    private Cat cat ;
    //试验3-------

Cat.java

package com.bjsxt.struts2.ognl;
public class Cat {
    private Dog friend;

    public Dog getFriend() {
        return friend;
    }

    public void setFriend(Dog friend) {
        this.friend = friend;
    }
    
    public String miaomiao(){
        return "miaomiao";
    }
}

Dog.java

package com.bjsxt.struts2.ognl;
public class Dog {
    private String name ;

    public Dog(){
        
    }
    
    public Dog(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public String toString(){
        return "dog:" + name;
    }   
}

说明:此时这里就构成了一个对象图,我们可以使用地址http://localhost:8080/Struts2_1900_OGNL/ognl.action?cat.friend.name=oudy进行访问,我们通过<s:property value="cat.friend.name"/>就可以取得相应的值。

3.访问值栈中对象的普通方法

ognl.jsp

<li>4.访问值栈中对象的普通方法:<s:property value="password.length()"/></li>
<li>5.访问值栈中对象的普通方法:<s:property value="cat.miaomiao()" /></li>

说明:访问普通属性中的方法我们可以直接调用,而访问对象中的方法也类似,这个比较简单。

4.方法值栈中action的普通方法

OgnlAction.javaa中有个名为m的方法,我们调用可以这样:
ognl.jsp

<li>6.访问值栈中action的普通方法:<s:property value="m()" /></li>

5.访问静态属性和方法

ognl.jsp

<li>7.访问静态方法:<s:property value="@com.bjsxt.struts2.ognl.S@s()"/></li>
<li>8.访问静态属性:<s:property value="@com.bjsxt.struts2.ognl.S@STR"/></li>
<li>9.访问Math类的静态方法:<s:property value="@@max(2,3)" /></li>

S.java

package com.bjsxt.struts2.ognl;
public class S {
    public static String STR = "STATIC STRING";
    
    public static String s(){
        return "static method";
    }
}

说明:我们在访问静态方法时一定要在struts.xml中设置<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>。访问格式是:@完整类名@静态方法/属性
而只有在访问Math类的时候使用两个@。

6.访问普通类的构造方法

ognl.jsp

<li>10.访问普通类的构造方法:<s:property value="new com.bjsxt.struts2.ognl.User(8)"/></li>

说明:类中我们覆写了toString方法,但是我在做试验的时候却失败,不知道为什么,语法应该没有错误,如果有谁看到,希望能帮我解决一下,不知道是不是struts2的设置变了。

7.访问集合(或数组)

ognl.jsp

<li>11.访问List:<s:property value="users"/></li>
<li>12.访问List中某个元素:<s:property value="users[1]"/></li>
<li>13.访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>
<li>14.访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
<li>15.访问Set:<s:property value="dogs"/></li>
<li>16.访问Set中某个元素:<s:property value="dogs[1]"/></li>
<li>17.访问Map:<s:property value="dogMap"/></li>
<li>18.访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li>
<li>19.访问Map中所有的key:<s:property value="dogMap.keys"/></li>
<li>20.访问Map中所有的value:<s:property value="dogMap.values"/></li>
<li>21.访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>

OgnlAction.java

    //试验4-------
    private List<User> users = new ArrayList<User>();
    //试验4-------
    
    //试验5-------
    private Set<Dog> dogs = new HashSet<Dog>();
    //试验5-------
    
    //试验6-------
    private Map<String, Dog> dogMap = new HashMap<String, Dog>();
    //试验6-------
    
    
    public OgnlAction(){
        //试验4-------
        users.add(new User(1));
        users.add(new User(2));
        users.add(new User(3));
        
        //试验5-------
        dogs.add(new Dog("dog1"));
        dogs.add(new Dog("dog2"));
        dogs.add(new Dog("dog3"));
        
        //试验6-------
        dogMap.put("dog100", new Dog("dog100"));
        dogMap.put("dog101", new Dog("dog101"));
        dogMap.put("dog102", new Dog("dog102"));
    }

最后我们给出试验结果:

11.访问List:[user :1, user :2, user :3]
12.访问List中某个元素:user :2
13.访问List中元素某个属性的集合:[1, 2, 3]
14.访问List中元素某个属性的集合中的特定值:1 | 1
15.访问Set:[dog:dog3, dog:dog1, dog:dog2]
16.访问Set中某个元素:
17.访问Map:{dog100=dog:dog100, dog101=dog:dog101, dog102=dog:dog102}
18.访问Map中某个元素:dog:dog101 | dog:dog101 | dog:dog101
19.访问Map中所有的key:[dog100, dog101, dog102]
20.访问Map中所有的value:[dog:dog100, dog:dog101, dog:dog102]
21.访问容器的大小:3 | 3

说明:

  • 1.注意在ongl中花括号可以代表一个集合,于是users.{age}表示的是age的一个集合。
  • 2.访问集合和访问数组的方式类似,这里不做试验。
  • 3.Set集合中是没有顺序的,所以第16个中取不到值。
  • 4.在ognl中单引号可以表示一个字符串。

8.投影(过滤)

ognl.jsp

<li>22.投影(过滤):<s:property value="users.{?#this.age==1}[0]"/></li>
<li>23.投影:<s:property value="users.{^#this.age>1}.{age}"/></li>
<li>24.投影:<s:property value="users.{$#this.age>1}.{age}"/></li>
<li>25.投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li>

说明:

  • 1.这里this表示当前对象,因为users是一个集合,于是会进行一个循环,循环到哪个对象,this就表示哪个对象。
  • 2.投影中只有上面三种方式:?#、^#、$#。第22表示判断哪个user对象的age为1,如果不加后面的[0],则打印出对象,同时对象加了中括号,如[user1],这就表示是一个集合,因为可能有多个对象的age复合条件。
  • 3.^#表示第一个age符合条件的对象。$#表示最后一个age符合条件的对象。

9.用 [] 访问元素

ognl.jsp

<li>26.[]:<s:property value="[0].username"/></li>

说明:

  • 1.当我们使用value="[0]"访问时会打印出值栈中从上到下的所有对象。如
    26.[]:[com.bjsxt.struts2.ognl.OgnlAction@1360826f, com.opensymphony.xwork2.DefaultTextProvider@5c053d81]
  • 2.当我们使用value="[0].username"访问时则会在action中找username这个属性,当在第一个action中找不到我们想要的属性时会到第二个action中去找,而一般我们什么时候值栈中才会有多个action呢?

ognl.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="ognl" extends="struts-default">
        <action name="ognl" class="com.bjsxt.struts2.ognl.OgnlAction">
            <result>/ognl.jsp</result>
        </action>
        <action name="test" class="com.bjsxt.struts2.ognl.TestAction">
            <result type="chain">ognl</result>
        </action>
    </package>
    
</struts>

可以看到当result的类型type="chain"时会出现多个action。此时我们使用地址:http://localhost:8080/Struts2_1900_OGNL/tesst.action进行访问,这时我们就可以在值栈中看到两个action。

最后我们给出struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.devMode" value="true" />
    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
    <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
    <include file="/com/bjsxt/struts2/ognl/ognl.xml"></include>
</struts>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容