OGNL(Object-Graph Navigation Language - 对象图导航语言)可以在值栈(ValueStack)上引用和操作数据的一种功能强大的表达式。
OGNL表达式提供使用简练的语法去引用java对象。
OGNL在基于字符串的视图层绑定java端数据属性。
在Structs2中,动作(action)驻留在栈值(ValueStack)中。 栈值(ValueStack)是动作上下文(ActionContext)的一部分。动作上下文(ActionContext)是全局存储区域,他保存着和处理请求相关的所有数据。
当一个请求进来,参数拦截器(params interceptor)将请求数据移动到栈值(ValueStack)上,现在OGNL负责将基于字符串的数据转换成相应的java类型,OGNL是通过使用可用的内建类型转换设置来实现的。
之后,当结果(Result)生成的时候,OGNL将在栈值(ValueStack)上java类型的属性转换成基于字符串的HTML输出。
动作上下文(ActionContext)是局部线程,也就是说存储在动作上下文(ActionContext)中的数据是单一的线程。这确保了Struts2的动作(action)是线程安全的。
struts2数据标签
Property标签
property标签被用来从值栈(ValueStack)或在动作上下文(ActionContext)中的其他对象,如application或seesion中取得对象。下面我们来看看如何使用property标签。
下面是AlbumInfoAction类:
public class AlbumInfoAction{
private String title;
private Artist artist;
public String populate()
{
title = "Thriller";
artist = new Artist("Michael Jackson","King of pop");
return "populate";
}
public String execute()
{
return "success";
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Artist getArtist() {
return artist;
}
public void setArtist(Artist artist) {
this.artist = artist;
}
}
下面是Artist类:
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<s:head />
<mce:style type="text/css"><!--
@import url(style.css);
--></mce:style><style type="text/css" mce_bogus="1">@import url(style.css);</style>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Album Details</title>
</head>
<body>
<div class="content">
<b>Album Title :</b> <s:property value="title" /> <br>
<s:push value="artist">
<b>Artist Name :</b> <s:property value="name" /> <br>
<b>Artist Bio :</b> <s:property value="bio" /> <br>
</s:push>
</div>
</body>
</html>
我们可以看到title是AlbumInfoAction的属性,所以可以直接访问它。但是name和bio是Artist类的属性,所以我们需要更深一步的访问,我们需要使用第二级OGNL表达式去访问它们。
Set标签
set标签被用来为属性值设置另外一个名称,可以帮助更快更方便的访问属性。当我们使用property标签访问artist的名字,需要更深一层的访问。取而代之,我们可以在动作上下文(ActionContext)中设置另外一个属性,并直接访问它。举例如下:
<s:set name="artistBio" value="artist.bio" />
<b>Album Title :</b> <s:property value="title" /> <br>
<b>Artist Name :</b> <s:property value="#artistName" /> <br>
<b>Artist Bio :</b> <s:property value="#artistBio" /> <br>
artistName和artisBio属性将被保存在动作上下文(ActionContext)中。引用它们的时候要用#objectName语法。
也可以将属性值保存到session中。
<s:set name="artistName" value="artist.name" scope="session" />
<s:set name="artistBio" value="artist.bio" scope="session" />
<b>Album Title :</b> <s:property value="title" /> <br>
<b>Artist Name :</b> <s:property value="#session['artistName']" /> <br>
<b>Artist Bio :</b> <s:property value="#session['artistBio']" /> <br>
用同样的方法,也可以将属性值保存到动作上下文(ActionContext)中的其他对象里去。
Push标签
我们可以使用push标签向值栈(ValueStack)中保存值。这个值会在值栈(ValueStack)的最上端,所以可以代替深层引用使用一级OGNL表达式进行引用。代码如下:
<b>Album Title :</b> <s:property value="title" /> <br>
<s:push value="artist">
<b>Artist Name :</b> <s:property value="name" /> <br>
<b>Artist Bio :</b> <s:property value="bio" /> <br>
</s:push>