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

来源:互联网 发布:岗亭设计图软件 编辑:程序博客网 时间:2024/06/08 16:30

最近来不及更新博客,博客内容可能要跳过系统管理模块,后面再来补写,不过我相信很快就会把系统管理这个模块的博客补上的。最近在做权限管理模块的时候发现用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地址

0 0
原创粉丝点击