Struts2 值栈(Value Stack)与OGNL

值栈(Value Stack)

Struts2 API中,有一个接口com.opensymphony.xwork2.util.ValueStack,称为值栈。

值栈在Struts2框架中是非常重要的对象,被存储在ActionContext对象中,因此可以在任何节点访问值栈中的内容。

ValueStack接口中有如下主要方法:

1、Object findValue(String expr):通过表达式查找值栈中对应的值。

2、void setValue(String expr,Object value):将对象指定表达式存到值栈中。

例:

通过请求参数传递title属性值,Testtitle.jsp

<body>
<s:form action="TestVS">
<s:textfield name="title" label="Input title"></s:textfield><br>
	<s:submit value="GO"></s:submit>
</s:form>
</body>

Action类,TestVSAction.java

package Action;

import java.util.ArrayList;
import java.util.List;

import VO.Customer;

public class TestVSAction {

	private Customer cust;
	private List<Customer> list;
	private String title;
	public Customer getCust() {
		return cust;
	}
	public void setCust(Customer cust) {
		this.cust = cust;
	}
	public List<Customer> getList() {
		return list;
	}
	public void setList(List<Customer> list) {
		this.list = list;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String execute(){
		cust = new Customer("Kate","123");
		list = new ArrayList<Customer>();
		list.add(new Customer("john","123"));
		list.add(new Customer("Tom","123"));
		list.add(new Customer("Jerry","123"));
		return "success";
	}
	
}
配置stuts.xml文件

    	</action>
    	    	<action name="TestVS" class="Action.TestVSAction">
    		<result name="success">/testvs.jsp</result>	
    	</action>
显示页面testvs.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="com.opensymphony.xwork2.util.ValueStack" %>
<%@page import="VO.Customer" %> 
<%@page import="java.util.*"%>
<!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>
<%
	ValueStack vs = (ValueStack)request.getAttribute("struts.valueStack");
	String title = vs.findString("title");
	Customer cust = (Customer)vs.findValue("cust");
	List<Customer> list = (List<Customer>)vs.findValue("list");
%><br>
	Title:<%=title%><br>
	cust.custname:<%=cust.getCustname() %><br>
	list.get(0).custname:<%=((Customer)list.get(0)).getCustname() %>
</body>
</html>

OGNL

OGNL是Object Graphic Navigation Language的缩写,即对象图导航语言,是一种功能强大的EL。

OGNL的几本语法非常简单,然而OGNL能支持丰富而复杂的表达式。OGNL表达式的基础单元称为导航链,简称链,如list[0].custname.length()就是一个链。

一个基础的链由如下部分组成:

1、属性名:如cust.custname.length()中的cust即属性名。

2、方法调用:如cust.custname.length()中的length()即方法调用。

3、数组、集合元素:如list[0].custname.length()中的list[0]即集合的第一个元素。

标准的OGNL会设定一个根对象(root对象),Struts2中的OGNL的根是值栈。Struts2中的OGNL上下文包括如下对象:

1、值栈:OGNL上下文的根对象。

2、application:访问ServletContext

3、session:访问HttpSession

4、request:访问HttpServletRequest

5、parameters:访问请求参数

6、attr:按照page-request-session-application顺序访问属性

值栈是OGNL上下文的根对象,所以可以直接访问,而application、session等对象不是根对象,如果需要访问这些对象,就需要使用#进行访问。

例如,#session.cust相当于ActionContext.getContext().getSession().getAttribute("cust"),即访问一个名字为cust的会话范围属性。


OGNL往往结合Struts2的标记使用,修改TestVSAction,在绘画范围内存储属性,代码如下:

		Map session = ActionContext.getContext().getSession();
		session.put("cust", cust);

上述代码中,在会话范围内存储一个名字为cust的属性,在testvs.jsp文件中,使用property标记显示OGNL表达式的值。

	OGNL:<br>
	<s:property value="cust.custname.length()"/><br>
	<s:property value="title"/><br>
	<s:property value="#session.cust"/><br>
上述代码中,cust.custname.length()将返回属性cust的custname变量的长度,#session.cust则返回会话范围内的cust属性。

OGNL对集合的操作也有很大改进,能够更为便捷地操作集合元素。例如,可以使用{e1,e2,s3}直接生成一个List对象,

可以使用#{key1:value1,key2:value2,key3:value3}生成一个Map对象。

对于集合类型,可以使用in和not in表示某元素是否在该集合中,用?表示获得符合逻辑的所有元素,用^表示获得第一个符合逻辑的元素,用$获得符合逻辑的最后一个元素。

	<s:iterator value="list.{?#this.age>20}">
		<li><s:property value="custname" /></li>
	</s:iterator>
上述代码中,首先将迭代属性list,获取集合中age属性大于20的Customer对象,并显示对象的custname属性。


#、%和$在OGNL表达式中经常出现,下面总结这三种符号的作用。

1、#号:#有三种作用。

访问非根对象:OGNL上下文的根对象时值栈,可以直接访问,当访问其他非跟对象时需要使用#,如#session.cust,可以获得回话的cust属性。

用于过滤集合:list.{?#this.age>20},取出年龄大于20的集合元素。

用来构造Map:ru#{"cust0":cust0,"cust1":cust1},可以构建一个Map对象,包含两对键值记录。

2、%号:%号用来计算OGNL表达式的值。

在Struts2标签库中,有的标签库属性是一个字符串,如url标签。在testvs.jsp中加入如下代码:

<p><s:url value="http://www.baidu.com"/></p>

其中value属性即将其值作为一个字符串输出,例如,通过http://localhost:8080/MyWork/TestVS.action?title=Java访问,跳转到testvs.jsp中显示url的值。

http://www.baidu.com?title=Java

然而,如果url标记的value值不是一个字符串,而是一个OGNL表达式,希望将OGNL表达式的运算值作为value的值,那么就要使用%,同事看一下不实用%的情况,

代码如下所示:

<span style="font-size:14px;">	<s:set name="foobar" value="#{'foo1':'bar1','foo2':'bar2'}" />
	<p>The value of key "fool" is <s:property value="#foobar['foo1']"/></p>
	<p><s:url value="#foobar['foo1']" /></p>
	<p><s:url value="%{#foobar['foo1']}"/></p></span>
输出:

<span style="font-size:14px;">The value of key "fool" is bar1

#foobar['foo1']

bar1</span><span style="font-size:14px;color:#3333ff;">
</span>
上述代码中,使用<s:url value="#foobar['foo1']" />输出url的值,url的值通过OGNL表达式生成,但是并没有使用%。接下来,使用<s:url value="%{#foobar['foo1']}"/>

输出另外一个url的值,url依然通过OGNL表达式生成,但是却使用了%。


可见,不实用%则并没有运算#foobar['foo1'],而是将表达式直接作为字符串输出。而是用了%的OGNL,则将#foobar['foo1']当做OGNL表达式进行了运算,

输出运算后的结果。


3、$号:$有两种作用。

国际化资源文件中使用:在国际化资源文件中,使用${}引用OGNL表达式。

Struts2的配置文件中使用:使用${}引用OGNL表达式。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值