sruts2中ognl表达式的原理

ognl是跟struts2的标签一起使用的。Struts2结合了ognl,在ognl中有根元素的概念,在Struts2中,根对象就是ValueStack,在任何流程当中,ValueStack最顶层的对象,一定是Action对象。除了ValueStack根对象外,Struts2还提供了几个常用的非根对象,叫做命名对象:parameters, request, session, application, attr。

若访问根对象,那么在表达式中直接访问即可,若访问的不是根对象,那么就要在要访问的对象的前面加上“#”,表示访问的不是根对象。

如何访问值栈中的对象的属性?若访问的是值栈中的对象的属性,那么struts2会从栈的顶部往下寻找和表达式中指定的属性匹配的属性,若找到,就不再继续往下找。也可以不从顶部开始找起,这时就要用到方括号去指定从哪里开始找起。

下面结合例子,看一下在Struts2中,ognl是怎么使用的:

package com.suo.action;

import java.util.Map;

public class Person{
	private String name;
	private int age;
	private String address;
	private String[] friends;
	private Cat cat;
	private Map<String,String> map;
	
	public Person(String name, int age, String address, String[] friends,
			Cat cat, Map<String, String> map) {
		this.name = name;
		this.age = age;
		this.address = address;
		this.friends = friends;
		this.cat = cat;
		this.map = map;
	}
	
	public Person() {
		
	}

	public Cat getCat() {
		return cat;
	}
	public void setCat(Cat cat) {
		this.cat = cat;
	}
	public Map<String, String> getMap() {
		return map;
	}
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String[] getFriends() {
		return friends;
	}
	public void setFriends(String[] friends) {
		this.friends = friends;
	}
}
package com.suo.action;

public class Cat {
	private String name;
	private int age;
	private String color;
	
	public Cat(String name, int age, String color){
		this.name=name;
		this.age=age;
		this.color=color;
	}
	
	public Cat(){
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
}
package com.suo.action;

import java.util.ArrayList;
/**
 * 实现了RequestAware,SessionAware,ApplicationAware接口,是为了取得Servlet API中的request等对象,
 * 这也是取得这些对象的一种方法。
 * 注意,这些属性一定要有对应的set方法。
 * @author hackerain
 */
public class OgnlAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{
	
	private Map<String,Object> request;
	private Map<String, Object> application;
	private Map<String, Object> session;
	
	private String username;
	private String password;
	
	private List<Person> list;

	public List<Person> getList() {
		return list;
	}

	public void setList(List<Person> list) {
		this.list = list;
	}

	@Override
	public void setRequest(Map<String, Object> request) {
		this.request=request;
	}
	
	@Override
	public void setApplication(Map<String, Object> application) {
		this.application=application;
	}
	
	@Override
	public void setSession(Map<String, Object> session) {
		this.session=session;
	}

	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;
	}
	
	@Override
	public String execute() throws Exception {
		request.put("hello", "suo");
		session.put("hello", "piao");
		application.put("hello", "rachel");
		
		Cat cat1=new Cat("cat1", 12, "red");
		Cat cat2=new Cat("cat2", 11, "blue");
		
		String[] friends1=new String[]{"gg1","gg2","gg3"};
		String[] friends2=new String[]{"mm1","mm2","mm3"};
		
		Map<String,String> map1=new HashMap<String,String>();
		Map<String,String> map2=new HashMap<String,String>();
		
		map1.put("key11", "value11");
		map1.put("key12", "value12");
		
		map2.put("key21", "value21");
		map2.put("key22", "value22");
		
		Person person1=new Person("suo",23,"changsha",friends1,cat1,map1);
		Person person2=new Person("piao",21,"changchun",friends2,cat2,map2);
		
		list=new ArrayList<Person>();
		list.add(person1);
		list.add(person2);
		
		return SUCCESS;
	}
}
login.jsp:
  
<body>
    <form action="OgnlAction">
    	username: <input type="text" name="username" width="20"><br>
    	password: <input type="password" name="password" width="20"><br>
    	<input type="submit" value="submit">
    </form>
</body>
ognl.jsp:

<%@ page language="java" import="java.util.*, com.opensymphony.xwork2.*, com.suo.action.OgnlAction" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'ognl.jsp' starting page</title>
  </head>
  
  <body>
  	--------------------------------------------<br>
  	
  	标签库实现:<br>
   	username: <s:property value="username"/><br>
   	password: <s:property value="password"/><br>
   	
   	<!-- 因为此处ValueStack为根对象,而Action对象又保存到ValueStack的最顶层,所以此处不用#号指定属性的对象 -->
   	--------------------------------------------<br>
   	 
   	用parameters命名对象实现:<br>
   	username: <s:property value="#parameters.username"/><br>
   	password: <s:property value="#parameters.password"/><br>
   	
   	<!-- 
   	此处用的是parameters命名对象,它和ValueStack根对象是处在同一个地位的,只是它不是根对象而已,所以
   	要访问命名对象中的属性,则要用#号指定对象名。request,session,application同理。
   	 -->
   	--------------------------------------------<br>
   	
   	底层实现:<br>
   	username: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getUsername() %><br>
   	password: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getPassword() %><br>
   	
   	<!-- peek()函数是返回栈的最顶部的对象,但是并不从栈中删除这个对象,最顶部的对象为Action对象 -->
   	
   	--------------------------------------------<br>
   	
   	用命名对象实现:<br>
   	request: <s:property value="#request.hello"/><br>
   	session: <s:property value="#session.hello"/><br>
   	application: <s:property value="#application.hello"/><br>
   	attr: <s:property value="#attr.hello"/><br>
   	
   	--------------------------------------------<br>
   	
   	底层实现:<br>
   	request: <%=((Map)ActionContext.getContext().get("request")).get("hello") %><br>
   	session: <%=ActionContext.getContext().getSession().get("hello") %><br>
   	application: <%=ActionContext.getContext().getApplication().get("hello") %><br>
   	attr: <%=((Map)ActionContext.getContext().get("attr")).get("hello") %><br>
   	
   	<!-- ActionContext是一个提供Action上下文环境的类,提供了getSession(),getApplication,get()等方法 -->
   	
   	--------------------------------------------<br>
   	
   	用标签库实现:<br>
   	person1.name:<s:property value="list[0].name"/><br>
   	person2.address:<s:property value="list[1].address"/><br>
   	
   	list.size: <s:property value="list.size"/><br>
   	list.isEmpty: <s:property value="list.isEmpty()"/><br>
   	
   	person1.cat: <s:property value="list[0].cat.name"/><br>
   	
   	person2.friend1: <s:property value="list[1].friends[0]"/><br>
   	
   	person1.map1: <s:property value="list[0].map"/><br>
   	person2.map2.key21: <s:property value="list[1].map['key21']"/><br>
   	
   	<!-- 值栈是根对象,且在值栈的最顶层的对象为Action对象,所以这里可以直接指定Action中的属性来访问 -->
   	
   	--------------------------------------------<br>
   	
   	底层实现:<br>
   	person1.name: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(0).getName() %><br>
   	person2.address: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(1).getAddress() %><br>
   	
   	list.size: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().size() %><br>
   	list.isEmpty: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().isEmpty() %><br>
   	
   	person1.cat: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(0).getCat().getName()%><br>
   	
   	person2.friend1: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(1).getFriends()[0] %><br>
   	
   	person1.map1: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(0).getMap() %><br>
   	person2.map2.key21: <%=((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(1).getMap().get("key21") %><br>
   	
   	
   	--------------------------------------------<br>
   	
   	
   	<!-- 过滤 -->
   	person.name.lenth>2: <s:property value="list.{? #this.name.length()>2}"/><br>
   	
   	person.iterator:<br>
   	<s:iterator value="list.{? #this.name.length()>2}">
   		<s:property value="name"/><br>
   		<s:property value="cat.name"/><br>
   		<s:property value="friends[0]"/><br><br>
   	</s:iterator>
   	
   	<!-- 投影 -->
   	persons.name: <s:property value="list.{name}"/><br>
   	
   	<s:iterator value="list.{name}">
   		<s:property/><br><!-- 这里已经是简单的属性了,不用写value,就可以取出来值了 -->
   	</s:iterator>
   	
  </body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值