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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容