最近来不及更新博客,博客内容可能要跳过系统管理模块,后面再来补写,不过我相信很快就会把系统管理这个模块的博客补上的。最近在做权限管理模块的时候发现用el/jstl表达式做回显和数据提交的时候遇到一些无法解决的问题,尤其是用jstl做checkbox的已选择默认打勾的回显遇到了技术上的难题,于是乎就是用起了Struts2的OGNL表达式来。
Struts2支持以下几种表达式语言:
- OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言;
- JSTL(JSP Standard Tag Library),JSP 2.0集成的标准的表达式语言;
- Groovy,基于Java平台的动态语言,它具有时下比较流行的动态语言(如Python、Ruby和Smarttalk等)的一些起特性;
- 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地址