OGNL表达式(Object-Graph
Struts2自行维护一个特定范围的“银行”,Action将数据放入其中,而JSP页面可从中取数据,表面上似乎看起来像是jsp可以直接访问Action数据。。
当Action属性不再是简单的值,而是某个对象,数组,集合时,就需要使用ognl表达式来访问这些对象,数组,集合内的数据了。
1)ognl的stack Context 和 ValueStack
ognl的Stack Context是整个ognl计算,求值的Context,而ValueStack只是Stack Context的根对象而已,ognl的Stack Context除了包括ValueStack这个根外,还包括parameters,request,application,attr等命名对象,Stack Context的根对象和普通命名对象的区别在于:
1.访问Stack Context里的命名对象需要在对象名之前添加“#”前缀。
例如访问student对象的stuName属性: #student.stuName
2.当访问Stack Context里的根对象时,不用加#
可以使用<s:debug />标签去查看程序的Stack Context 和ValueStack
使用<s:debug/>如下:
2)访问除了根对象以外的其他命名对象
parameter对象:用于访问Http请求参数。例如#parameter["uname"]或#parameter.uname,用于返回调用HttpServletRequest的getParameter("uname")方法的返回值。
request对象:用于访问HttpServletRequest的属性。例如#request["uname"]或#request.uname,用于返回调用HttpServletRequest的getAttribute("uname")方法的返回值。
session对象:用于访问HttpSession的属性,例如#session["username"]或#session.username,用于返回调用HttpSession的getAttribute("username")方法的返回值。
application对象:用于访问ServletContext的属性,例如#application["foo"]或#application.foo,用于返回调用ServletContext的getAttribute("foo")方法的返回值。
attr对象:该对象将依次搜索如下对象:PageContext,HtttpServletRequest,HttpSession,ServletContext中的属性。
写个小例子,Action中这么写:
public class LoginAction{
private String uname;
private String pwd;
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String login() throws Exception{
if("zhangsan".equals(getUname())&&"123".equals(getPwd())){
ActionContext.getContext().getSession().put("username", uname);
student = new Student();
student.setStuNumber(2009);
student.setStuName("jihaixiao");
student.setSex("男");
return "success";
}else{
return "error";
}
}
}
然后配置struts.xml,如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<!-- 这句用来配置动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<!-- 开发者模式 -->
<constant name="struts.devMode" value="false" />
<package name="user" extends="struts-default" >
<action name="loginAction" class="com.test.action.LoginAction" method="login">
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
</struts>
在success.jsp中这么写:
<h4>登陆成功<s:property value="#session.username"/></h4>
<h5>我的姓名叫:<s:property value="student.StuName"/></h5>
因为系统创建了Action实例后,该实例就被保存到ValueStack里去,故无需书写#即可访问Action属性。
结果如下:
3)ognl的集合操作
使用ognl可以直接创建集合对象,直接创建List类型集合的语法是:{e1,e2,e3........},不同元素用,隔开,创建Map的集合的语法是 # {key1:value1,key2:value2......}
对于集合,ognl提供了两个运算符,in和not in,其中in 判断该元素是否在指定集合中, not in正好相反。
ognl还允许通过某个规则取得集合的子集:
?:取出所有符合选择逻辑的元素
^:取出符合选择逻辑的第一个元素
$:取出符合选择逻辑的最后一个元素
books.{?#this.price>35} 就是取出所有价格大于35的book的集合
4)访问静态成员
ognl提供了一种访问静态成员(静态方法,静态属性)的方式,但struts2默认是关闭的,需要在struts.xml加入这么一句来开启这个功能:
<constant name="struts.ognl.allowStaticMethodAccess" value="true" />
开启了功能以后,可以通过这样的形式来访问静态成员:
@className@staticField
@className@staticMethod(val....)
例如,在success.jsp加入这么两句话:
<div><p>系统变量:<s:property value="@java.lang.System@getenv('JAVA_HOME')"/></p></div>
<div><p>圆周率:<s:property value="@java.lang.Math@PI"/></p></div>
看结果: