SSH实战OA 04:Struts2的OGNL表达式

最近来不及更新博客,博客内容可能要跳过系统管理模块,后面再来补写,不过我相信很快就会把系统管理这个模块的博客补上的。最近在做权限管理模块的时候发现用el/jstl表达式做回显和数据提交的时候遇到一些无法解决的问题,尤其是用jstl做checkbox的已选择默认打勾的回显遇到了技术上的难题,于是乎就是用起了Struts2的OGNL表达式来。

Struts2支持以下几种表达式语言:

  1. OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言;
  2. JSTL(JSP Standard Tag Library),JSP 2.0集成的标准的表达式语言;
  3. Groovy,基于Java平台的动态语言,它具有时下比较流行的动态语言(如Python、Ruby和Smarttalk等)的一些起特性;
  4. Velocity,严格来说不是表达式语言,它是一种基于Java的模板匹配引擎,具说其性能要比JSP好。

Jstl在Struts和Spring Mvc都得到支持,今天的主题是来谈谈OGNL。

最简单的使用OGNL表达式的案例如下:

ognl.jsp

<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>OGNL表达式语言学习</title>
</head>
<body>
    <ol>
        <li>访问值栈中action的普通属性username: <s:property value="username"/>, 
            password: <s:property value="password" />
        </li>
    </ol>

    <s:debug></s:debug>
</body>
</html>

就如我们的JSTL一样,引入OGNL表达式也需要引入我们的标签裤taglib。

OgnlAction.java

public class OgnlAction extends ActionSupport {

    private String username;

    private String password;

    @Override
    public String execute() {

        return SUCCESS;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

在浏览器中输入下列的url地址:

http://localhost:8080/struts_ognl/ognl.action?username=shizongger&password=5476499

这个url向后台的action传入username和password,这两个值被放在值栈中传递到jsp页面,ognl表达式解析出这两个属性并显示在页面。

项目的struts.xml配置如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
    <include file="/com/shizongger/ognl/ognl.xml"/>

</struts>

这里需要引入一个xml文件,ognl.xml的内容:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

    <package name="ognl" extends="struts-default">

        <action name="ognl" class="com.shizongger.ognl.OgnlAction">
            <result>/ognl.jsp</result>
        </action>
</struts>

这是项目的最小配置方式,下面给出一些教全面的案例,包括访问值栈的值,集合List,Set和Map的访问方式等等。

ognl.jsp

    <ol>
        <li>访问值栈中action的普通属性username: <s:property value="username"/>, 
            password: <s:property value="password" />
        </li>
        <li>密码是:<s:password value="password" id="password" name="password" /></li>
        <li>访问对象栈中属性:name:<s:property value="user.name" /> age:<s:property value="user.age"/></li>
        <li>访问值栈中对象的普通属性(get set方法):
            <s:property value="user.age"/> | 
            <s:property value="user['age']"/> | 
            <s:property value="user[\"age\"]"/> | 
        </li>
        <li>访问值栈中的普通属性(get set方法):<s:property value="cat.friend.name" /></li>
        <li>字符串<s:property value="username" />,字符串长度(用法一):<s:property value="username.length()"/></li>
        <li>访问值栈中对象的普通方法:<s:property value="cat.shout('sam')" /> </li>
        <li>访问值栈中action的普通方法:<s:property value="toUpperCase(\"Hello My Name is Shizongger\")" /> </li>
        <li>访问静态方法:转为小写之后的字符串是=[<s:property value="@com.shizongger.ognl.Common@toLowerCase('Hello Csdn')" />],
            长度是:<s:property value="@com.shizongger.ognl.Common@count('Hello Csdn')" /></li>
        <li>访问java.lang包下类的静态方法一:<s:property value="@java.lang.Math@abs('-123')" /></li>
        <li>访问java.lang包下类的静态方法二:<s:property value="@@abs('-123')" /></li>
        <li>访问普通类的构造方法:<s:property value="new com.shizongger.ognl.User.User(22, 'lily')" /></li>
        <hr />

        <li>访问List<s:property value="users" /></li>
        <li>访问List的第一个元素<s:property value="users[0]"/></li>
        <li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
        <li>访问List链表中的年龄集合:<s:property value="users.{name}" /></li>
        <li>访问Lis的年龄集合中的第一个: age=<s:property value="users.{age}[0]" />, 
            name=<s:property value="users.{name}[0]"/></li>
        <li>访问Set集合:<s:property value="dogs" /></li>
        <li>访问Set集合的第一个元素<s:property value="dogs[0]" /> </li>
        <li>访问Map的元素:<s:property value="dogMap"/></li>
        <li>访问Map中某个元素:
            <s:property value="dogMap.001"/> | 
            <s:property value="dogMap['001']"/> | 
            <s:property value="dogMap[\"001\"]"/>
        </li>
        <li>访问Map中所有的keys:<s:property value="dogMap.keys" /> </li>
        <li>访问Map中所有的values<s:property value="dogMap.values" /></li>
        <li>得到Map的长度size:<s:property value="dogMap.size()" />|<s:property value="dogMap.size" /></li>
        <hr />

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

OgnlAction.java

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.opensymphony.xwork2.ActionSupport;

public class OgnlAction extends ActionSupport {

    private String username;

    private String password;

    private User user;

    private Cat cat;

    private List<User> users = new LinkedList<User>();

    private Set<Dog> dogs = new HashSet<Dog>();

    private Map<String, Dog> dogMap = new HashMap<String, Dog>();

    public OgnlAction() {
        dogs.add(new Dog("山姆"));
        dogs.add(new Dog("追风"));

        dogMap.put("001", new Dog("Dog001"));
        dogMap.put("002", new Dog("Dog002"));
        dogMap.put("003", new Dog("Dog003"));
    }

    @Override
    public String execute() {
        users.add(new User(1, "shizongger"));
        users.add(new User(2, "lily"));
        users.add(new User(3, "admin"));
        users.add(new User(4, "root"));
        System.out.println("users list的长度:" + users.size());
        cat = new Cat();
        cat.setFriend(new Dog("山姆"));

        return SUCCESS;
    }

    /**
     * 将传递过来的字符转换为大写
     * @return 返回大写字母
     */
    public String toUpperCase(String str) {
        System.out.println("传递过来的原字符串:" + str);

        return str.toUpperCase();
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public List<User> getUsers() {
        return users;
    }

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

    public Set<Dog> getDogs() {
        return dogs;
    }

    public void setDogs(Set<Dog> dogs) {
        this.dogs = dogs;
    }

    public Map<String, Dog> getDogMap() {
        return dogMap;
    }

    public void setDogMap(Map<String, Dog> dogMap) {
        this.dogMap = dogMap;
    }

}

还有用到的工具类Common.java

/**
 * common工具类
 * @author shizongger
 *
 */
public class Common {

    /**
     * 将字符串转换为小写
     * @param str 原字符串
     * @return
     * @throws Exception
     */
    public static String toLowerCase(String str) throws Exception {
        if(str == null || "".equals(str)) {
            return "NULL";
        }

        return str.toLowerCase();
    }

    public static int count(String str) throws Exception {
        if(str == null || "".equals(str)) {
            return 0;
        }

        return str.length();
    }
}

并且用到3个javaBean,分别如下:

User.java

public class User {
    private int age;

    private String name;

    public User() {
    }

    public User(int age, String name) {
        System.out.println("[age = " + age + ",name = " + name + "]");

        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User [age=" + age + ", name=" + name + "]";
    }

}

Cat.java

public class Cat {

    private Dog friend;

    public Dog getFriend() {
        return friend;
    }

    public void setFriend(Dog friend) {
        this.friend = friend;
    }

    public String shout(String str) {
        return "miaomiao, my name is " + str;
    }
}

Dog.java

public class Dog {

    private String name;

    public Dog() {

    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "dog: " + name;
    }
}

这三个javaBean都重写了toString方法,为了方便在jsp页面的输出。在ongl的jsp页面中,为了随便查看和调试各种值,可以用< s:debug>标签来输出值栈中的值。

浏览器输出如图:
这里写图片描述

可运行案例免积分下载csdn_download地址

猜你喜欢

转载自blog.csdn.net/zhang5476499/article/details/70881659