Struts2框架学习之四:OGNL表达式

前言

OGNL表达式的全称是Object Graph Navigation Language,就是对象导航图语言。使用OGNL表达式可以使用简单的语法设置以及读取Java对象的值,还包括调用对象的方法,实现类型转换等功能。而且,OGNL表达式的强大还不止于此。我们知道在JSP中已经内置了表达式语言,那么使用OGNL表达式的优势是什么呢?主要是语法变得更简单以及功能的更强大。这两点会在后面的内容加以体现。

对象的操作

使用OGNL表达式实现对象的操作,包括以下几个方面:

1、访问JavaBean属性
2、调用对象的方法
3、调用静态方法和静态字段
4、调用构造方法

1、访问JavaBean属性

这是Struts2中最常使用的功能了,首先创建如下的JavaBean:

package com.rhwayfun.struts2.model;

public class User {

    private Address address;
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
}

那么实现访问JavaBean属性有以下两个表达式:nameaddre.street。第一个表达式的Java实现代码是user.getName(),第二个表达式的Java实现代码是user.getAddress().getStreet()

2、访问对象的普通方法

访问JavaBean属性的时候,实际上就是调用了对象的getter方法,所以需要调用对象的普通方法的时候就可以使用类似Java代码的方式直接访问对象的方法。比如,需要把User对象的name属性转为大写的形式,那么OGNL表达式可以写为name.toUpperCase()

3、调用静态方法和静态字段

访问静态字段和方法的时候,需要使用如下的语法格式:

//访问静态方法
@class@method(args)
//访问静态字段
@class@filed
/*
    需要注意的是,class需要给出完整的类名,如果省略不写的话,默认访问的是java.lang.Math类。
*/

4、访问构造方法

访问构造方法的时候,可以使用new关键字创建一个对象,但是在使用的时候必须指出类的完整包名。

集合的操作

集合的操作是web开发中经常使用到的,下面对使用OGNL表达式创建集合做一个小结:

1、创建列表

比如需要创建一个列表,语法就是使用花括号,列表元素之间使用逗号隔开,比如:

{"liubei","guanyu","zhaoyun"}

其实现的Java代码就是创建一个ArrayList对象,把这三个元素添加到List中。访问列表元素的时候,使用索引就可以成功访问,比如需要访问第一个元素,那么表达式可以写成{"liubei","guanyu","zhaoyun"}[0]

2、创建数组

在OGNL中创建数组的语法与Java中是一致的,比如创建三个元素的整型数组:new int[]{1,2,3}。那么访问数组元素的时候同样是使用索引,比如访问第一个元素:new int[]{1,2,3}[0]。

3、创建Map

创建Map的语法与Java中不太一样,使用的语法如下:

#{"key1":"value1","key2":"value2",....}

在使用上述语法创建的Map与在Java中创建HashMap是一样的,然后把其中的元素放入其中。当然可以使用@class@{"key1":"value1",...}的语法创建指定类型的Map。访问Map元素是通过key访问的,比如访问Map的第一个元素,使用表达式map["first"]或者map.first

OGNL表达式实战

首先我们需要创建一个Action类,代码如下:

package com.rhwayfun.struts2.action;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.rhwayfun.struts2.model.User;

public class OgnlAction extends ActionSupport{
    private static final long serialVersionUID = 1L;
    private List users;
    private static String str = "ognl";

    public String execute(){
        //获取web元素,以便访问Servlet API
        ActionContext context = ActionContext.getContext();
        //获取request对象
        @SuppressWarnings("unchecked")
        Map request = (Map) context.get("request");
        //获取session对象
        Map session = context.getSession();
        //获取Application对象
        Map application = context.getApplication();
        //分别在三个域对象中设置一个值
        request.put("msg", "我是request元素");
        session.put("msg", "我是session元素");
        application.put("msg", "我是application元素");

        //创建两个User对象
        users = new ArrayList();
        User u1 = new User();
        u1.setName("zhaoyun");
        u1.setAge(23);
        User u2 = new User();
        u2.setName("zhangfei");
        u2.setAge(26);
        //添加到集合中
        users.add(u1);
        users.add(u2);

        return SUCCESS;
    }

    public List getUsers() {
        return users;
    }

    public void setUsers(List users) {
        this.users = users;
    }


}

然后在struts.xml文件配置该action,如下:


        <action name="ognl" class="com.rhwayfun.struts2.action.OgnlAction">
            <result>/ognl.jspresult>
        action>

接着编写ognl.jsp页面,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<html>
  <head>
    <base href="<%=basePath%>">

    <title>OGNL表达式title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    

  head>

  <body>
   <p>1、访问web元素中的值p>
   <p>request:<s:property value="#request.msg"/>p>
   <p>session:<s:property value="#session.msg"/>p>
   <p>application:<s:property value="#application.msg"/>p>
   <hr>
   <p>2、访问listp>
   <p>
   <s:iterator value="users" var="u">
        <s:property/><br>
   s:iterator>
   p>
   <p>3、通过OGNL表达式直接创建列表并访问p>
   <p>
        创建一个列表:{'赵云','刘备','张飞'}<br>
        <s:set name="list" value="{'赵云','刘备','张飞'}">s:set>
        
        <s:iterator value="#list" var="o">
            <s:property/><br>
        s:iterator><br>
        访问列表的元素个数:<s:property value="#list.size()"/><br>
        访问列表的第二个元素:<s:property value="#list[1]"/>
   p>
   <p>4、创建一个数组并访问p>
   <p>
        <s:set name="array" value="new int[]{1,2,3}">s:set>
        <s:iterator value="#array" var="o">
            <s:property/> 
        s:iterator>
   p>
   <p>5、构造map并访问p>
   <p>
        <s:set name="map" value="#{'中国':'北京','美国':'纽约','俄罗斯':'莫斯科' }">s:set>
        
        遍历该map(第一种方式):
        <s:iterator value="#map" var="m">
            <s:property/> 
        s:iterator>
        <br>
        遍历该map(第二种方式):
        <s:iterator value="#map" var="m">
            <s:property value="key"/>=<s:property value="value"/> 
        s:iterator>
        <br>
        访问第一个元素(不使用%):<s:property value="#map['中国']"/><br>
        访问第一个元素(使用%):<s:property value="%{#map['中国']}"/><br>
        获取该map所有的key:<s:property value="#map.keys"/><br>
        获取该map所有的value:<s:property value="#map.values"/>
   p>
   <p>6、访问静态方法和字段p>
   <p>
        <code>访问Math类的floor方法(由于Math类是Struts2中默认的类<br>,
        所以在调用此类方法的时候,其中的class可以不写出)code><br>
        访问静态方法::
        <s:property value="@java.lang.Math@floor(32.56)"/>
        等价于
        <s:property value="@@floor(32.56)"/>
        <br>
        <s:property value="@java.util.Calendar@getInstance()"/><br>
        访问静态属性:
        <s:property value="@com.rhwayfun.struts2.action.OgnlAction@str"/>
   p>
   <p>7、访问构造方法p>
   <p>
        访问User类的有参构造方法:
        <s:property value="new com.rhwayfun.struts2.model.User('张角',43).name"/>
   p>
   <p>8、if/else判断语句p>
   <p>
        <s:if test="'关羽'in {'关羽','赵云','黄忠'}">
            关羽在集合中
        s:if>
        <s:elseif test="'赵云' in {'赵云','关羽','黄忠'}">
            赵云在集合中
        s:elseif>
        <s:else>
            关羽不在集合中
        s:else>
        <br>
        <s:if test="#request.msg not in #list">
            请求消息不在集合中
        s:if>
   p>
   <p>9、迭代标签完整版p>
   <p>
        创建一个list列表:abcde<br><s:set name="list2" value="{'a','b','c','d','e'}">s:set>
        <s:iterator value="#list2" var="c" status="s">
            索引:<s:property value="#s.getIndex()"/> 值:<s:property/>
             当前迭代数量:<s:property value="#s.getCount()"/><br>
        s:iterator>
   p>
   <p>10、获取属性范围内的值p>
   <p>
        <%  request.setAttribute("req", "request对象");
            request.getSession().setAttribute("ses", "session对象");
            request.getSession().getServletContext().setAttribute("app", "application对象");
         %>
         request:<s:property value="#request.req"/><br>
         session:<s:property value="#session.ses"/><br>
         application:<s:property value="#application.app"/>

   p>
  body>
html>

通过以上的ognl.jsp页面对平时开发中经常使用的语法进行了归类和测试,具体的内容已经在代码给出注释了,这里不再赘述。

Struts 2中的值栈

值栈就是用来存放对象的,类似于正常的栈,符合先进后出的特性。在值栈中可以存放、查询和删除对象。值栈是Struts 2框架的核心。值栈实际上是一个接口(该接口是com.opensymphony.xwork2.util.ValueStack),我们平时在开发是使用的标签实际上使用的是该接口的实现类,也就是com.opensymphony.xwork2.ognl.OgnlValueStack类。

你可能感兴趣的:(Struts2框架学习之四:OGNL表达式)