一.OGNL表达式概述
Struts2支持OGNL表达式
OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
webwork2和现在的Struts2.x中使用OGNL取代原来的EL来做界面数据绑定,所谓界面数据绑定,也就是把界面元素(例如一个textfield,hidden)和对象层某个类的某个属性绑定在一起,修改和显示自动同步。
二.OGNL测试代码
直接上代码,具体解释见代码注释
OGNL.java
/*
OGNL表达式:对象视图导航语言
与EL表达式相似,但比EL表达式强大
关于EL表达式:
11大内置对象可以取值
requestscope
sessionscope
applicationscope
pagescope
pagecontext
params
paramvalues
header
headervalues
cookie
initparams
关于OGNL表达式:只有一个内置对象可以取值
OGNL context:OGNL上下文对象包括两部分
root部分:可以放置任何对象
context部分:只能放置map对象
*/
//测试OGNL
public class OGNL {
@Test
//OGNL操作代码演示
public void funone() throws OgnlException{
//准备root
User root=new User("tom",18);
//准备Context
Map<String, User> context=new HashMap<String, User>();
context.put("u1", new User("jake",19));
context.put("u2", new User("rose",20));
//准备OGNL context
OgnlContext oc=new OgnlContext();
oc.setRoot(root);
oc.setValues(context);
/*写OGNL*/
//取出root中user对象的name属性
//直接写属性
String name= (String) Ognl.getValue("name", oc, oc.getRoot());
System.out.println(name);
//取出Context中user对象的name属性
//#代表从context部分取值
name= (String) Ognl.getValue("#u1.name", oc, oc.getRoot());
System.out.println(name);
//为root中user对象的name属性赋值
name= (String) Ognl.getValue("name='jerry'", oc, oc.getRoot());
System.out.println(name);
name= (String) Ognl.getValue("name", oc, oc.getRoot());
System.out.println(name);
//为Context中user对象的name属性赋值
name= (String) Ognl.getValue("#u1.name='cat'", oc, oc.getRoot());
System.out.println(name);
name= (String) Ognl.getValue("#u1.name", oc, oc.getRoot());
System.out.println(name);
//调用root中user对象的方法
name= (String) Ognl.getValue("setName('lililili')", oc, oc.getRoot());
System.out.println(name);
name= (String) Ognl.getValue("getName()", oc, oc.getRoot());
System.out.println(name);
//调用Context中user对象的方法
name= (String) Ognl.getValue("#u1.setName('babababa')", oc, oc.getRoot());
System.out.println(name);
name= (String) Ognl.getValue("#u1.getName()", oc, oc.getRoot());
System.out.println(name);
//调用静态方法,得到返回值
//@+全路径+@+方法名(参数)
name= (String) Ognl.getValue("@cjx.user.Util@echo('hello!')", oc, oc.getRoot());
System.out.println(name);
//得到静态属性
double pi= (double) Ognl.getValue("@java.lang.Math@PI", oc, oc.getRoot());
System.out.println(pi);
pi= (double) Ognl.getValue("@@PI", oc, oc.getRoot());//java.lang.Math是内置对象
System.out.println(pi);
//创建对象之list对象
Integer in= (Integer) Ognl.getValue("{'ab','bb','cb','db'}.size()", oc, oc.getRoot());
System.out.println(in);
name= (String) Ognl.getValue("{'ab','bb','cb','db'}[1]", oc, oc.getRoot());
System.out.println(name);
//创建对象map对象
//#代表map对象
in= (Integer) Ognl.getValue("#{'name':'tom','age':'18'}.size()", oc, oc.getRoot());
System.out.println(in);
name= (String) Ognl.getValue("#{'name':'tom','age':'18'}['name']", oc, oc.getRoot());
System.out.println(name);
}
}
OgnlTestlAction.java
public class OgnlTestlAction extends ActionSupport{
/*为什么OGNL表达式会取到值?
* OGNL与Struts2的整合
Struts2为ognl准备了一个ValueStack对象,作为ognl取值范围
ValueStack(ognl的取值域)
|-Root 栈
|-Context ActionContext(数据中心)
栈 => 默认放置当前访问的Action对象
ActionContext
|- request
|- response
|- servletContext
|- requestScope
|- sessionScope
|- applicationScope
|- parameters
|- attrs
*获得原生ServletAPI.详见/struts2/src/cjx/api/ServletAPI.java
ActionContext 数据中心
|-request
|-response
|-ServletContext
|-requestScope
|-sessionScope
|-applicationScope
|-params
|-attrs
....
//获得ActionContext
ActionContext.getContext();
|-requestScope
|-sessionScope
|-applicationScope
|-params
|-attrs
//获得ActionContext中原生对象的工具类
ServletActionContext
|-request
|-response
|-ServletContext
*OGNL与Struts2结合的应用
|- 参数接收 => struts2中的参数交给ognl引擎处理
|- 配置文件中 => ${ognl表达式}
|- 标签 => struts2标签
*/
private String name;
public String execute() throws Exception {
System.out.println("OgnlTestlAction.得到name参数:"+name);
return "success";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
OgnlActionStruts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="ognl" namespace="/ognl" extends="struts-default">
<action name="ognlaction" class="cjx.ojnl.OgnlAction" >
<result name="success" type="redirectAction">
<param name="actionName">ognltestaction</param>
<param name="namespace">/ognl</param>
<param name="name">${name}</param>
</result>
</action>
<action name="ognltestaction" class="cjx.ojnl.OgnlTestlAction" >
<result name="success" >/ognl.jsp</result>
</action>
</package>
</struts>
OgnlAction.java
public class OgnlAction extends ActionSupport{
/*在ognl.jsp中点击测试后
测试ognl:根据配置会先进入cjx.ojnl.OgnlAction
在cjx.ojnl.OgnlAction中为name属性赋值了
根据配置会redirectAction到ognltestaction
param属性中name属性在Struts2中不存在
所以Struts2会将其作为参数传递,利用ognl表达式取值
利用ognl表达式动态取值,地址栏会传递参数
*/
private String name;
public String execute() throws Exception {
System.out.println("OgnlAction.name被赋值为:"+name);
return "success";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ognl.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/ognl/ognlaction" method="post">
<input type="text" name="name"><br>
<input type="submit" value="测试ognl" >
</form><br>
</body>
</html>
TagAction.java
public class TagAction extends ActionSupport{
public String execute() throws Exception {
List<String> list= new ArrayList<String>();
list.add("tom");
list.add("rose");
list.add("jack");
list.add("jerry");
ActionContext.getContext().put("list", list);
this.addActionError("这是一个来自TagAction的错误信息!");
return SUCCESS;
}
}
TagActionStruts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="tag" namespace="/tag" extends="struts-default">
<action name="tagaction" class="cjx.tag.TagAction" >
<result name="success" >/tag.jsp</result>
</action>
</package>
</struts>
tag.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>tag</title>
</head>
<body>
遍历标签iterator <br>
1.取栈顶元素<br>
<s:iterator value="#list">
<s:property/><br>
</s:iterator>
2.遍历元素<br>
<s:iterator value="#list" var="name">
<s:property value="#name"/><br>
</s:iterator>
3.计次遍历
<s:iterator begin="1" end="100" step="2">
<s:property/> -
</s:iterator><br>
if else elseif标签 <br>
<s:if test="#list.size()==4">
list长度为4<br>
</s:if>
<s:elseif test="#list.size()==5">
list长度为5<br>
</s:elseif>
<s:else>
list长度不为4和5<br>
</s:else>
取值标签property <br>
<s:property value="#list.size()"/><br>
<s:property value="#session.user.name"/><br>
<br>表单标签<br>
form theme="simple"可以取消Struts2提供的样式
<s:form action="ognlaction" namespace="/ognl">
<s:textfield name="name" label="用户名" ></s:textfield>根据栈中的属性自动回显
<s:password name="password" label="密码"></s:password>
<s:radio list="#{1:'男',2:'女'}" name="sex" label="性别"></s:radio>
<s:checkboxlist list="{'运动','游戏'}" name="like" label="爱好"></s:checkboxlist>
<s:select list="{'本科','硕士','院士'}" headerKey="" headerValue="请选择" name="edu" label="学历"></s:select>
<s:file name="photo" label="照片"></s:file>
<s:textarea name="desc" label="个人简历" ></s:textarea>
<s:submit value="提交"></s:submit>
</s:form>
<br>actionerror标签:取出错误信息<br>
<s:actionerror/><br>
</body>
</html>
User.java
public class User {
private String name;
private Integer age;
private Date date;
public User() {
super();
}
public User(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", date=" + date + "]";
}
}
Util.java
public class Util {
//回音方法,用于测试
public static Object echo(Object o){
return o;
}
}
不要忘了主配置文件struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 引入其他配置文件 -->
<include file="cjx/ojnl/OgnlActionStruts.xml"></include>
<include file="cjx/tag/TagActionStruts.xml"></include>
</struts>