OGNL概述

  1. OGNL同EL表达式类似,但又比JSTL功能强大且高效。
  2. 主要在struts2里操作值栈数据
  3. 一般把ognl表达式和struts2标签结合起来使用
  4. ognl不是struts2的一部分,只不过经常和struts2搭配起来使用
  5. jar包

如何使用ognl表达式和struts2标签

  1. ognl的使用
  2. 在jsp页面中引入struts2标签库
  3. 简单示例

什么是值栈

  1. 在struts2里提供的一种存储机制,类似于域对象,可进行存储与取数据
  2. 在Action中存放数据到值栈中,在jsp页面中进行取值操作
  3. 值栈的存储位置
    1)每次创建Action的时候,就会创建一个Action对象(Action每调用一次创建一次,而Servlet只创建一次)
    2)在每个Action对象里只存在一个值栈对象

值栈的结构

  1. 值栈分为两部分
    1)root(一般在root里操作数据)和context
    2)root的结构是list,继承自ArrayList
    3)context的结构是map,实现了Map接口
  2. context的结构图
  3. 在struts.xml配置文件中添加如下内容(必须先访问Action,再访问jsp页面进行查看)
  4. 在jsp页面中使用<s:debug></s:debug>标签
  5. 页面访问该Action(点击Debug查看值栈的结构,下图是root的结构图)

获取值栈对象

  1. 注意:每个Action中只存在一个值栈对象
package tqb.valuestack;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

public class Demo1 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		/* * 获取值栈对象 * 每个Action中拥有一个值栈对象 */
		ActionContext context = ActionContext.getContext();
		
		/* * 判断值栈对象是否只存在一个 */
		ValueStack stack1 = context.getValueStack();
		ValueStack stack2 = context.getValueStack();
		
		System.out.println(stack1 == stack2);//true
		return SUCCESS;
	}
}

向值栈放数据的三种方式

  1. 只用值栈对象的set方法
package tqb.valuestack;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

/** * 向值栈中放数据的三种方式 * 第一种:set方法 * @author tqb * */
public class Demo2 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		/* * 1.获取值栈对象 */
		ActionContext context = ActionContext.getContext();
		ValueStack stack = context.getValueStack();
		
		/* * 调用值栈对象的set方法(处于栈顶位置) * 结构:java.util.HashMap */
		stack.set("username", "lisi");
	}
}

  1. 只用值栈对象的push方法
package tqb.valuestack;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

/** * 向值栈中放数据的三种方式 * 第二种:push方法 * @author tqb * */
public class Demo2 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		/* * 1.获取值栈对象 */
		ActionContext context = ActionContext.getContext();
		ValueStack stack = context.getValueStack();

		/* * 调用值栈对象的push方法(处于栈顶位置) * 结构:java.lang.String */
		stack.push("push...");
		return SUCCESS;
	}
}

  1. 在Action中定义变量,生成变量的get方法
package tqb.valuestack;

import com.opensymphony.xwork2.ActionSupport;

/** * 向值栈中存放数据的第三种方法 * @author tqb * */
public class Demo3 extends ActionSupport {
	//定义变量
	private String name;
	//生成get方法
	public String getName() {
		return name;
	}
	
	@Override
	public String execute() throws Exception {
		//给变量进行赋值
		name="zhangsan";
		return SUCCESS;
	}

}

向值栈中添加对象

  1. 定义对象变量
  2. 生成对象变量的get方法
  3. 在方法中向变量赋值
package tqb.valuestack;

import com.opensymphony.xwork2.ActionSupport;

import tqb.entity.User;

/** * 向值栈中添加对象 * @author tqb * */
public class Demo4 extends ActionSupport {
	// 定义实体对象
	private User user;
	// 生成get方法
	public User getUser() {
		return user;
	}
	
	@Override
	public String execute() throws Exception {
		// 给对象赋值
		user = new User();
		user.setUsername("wangwu");
		user.setPassword("123456");
		
		return SUCCESS;
	}
}

向值栈中添加List集合

  1. 定义list集合变量
  2. 生成list集合变量的get方法
  3. 方法内赋值
package tqb.valuestack;

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

import com.opensymphony.xwork2.ActionSupport;

import tqb.entity.User;

/** * 向值栈中添加list集合 * @author tqb * */
public class Demo5 extends ActionSupport{
	// 定义list集合
	List<User> list = new ArrayList<User>();
	// 生成get方法
	public List<User> getList() {
		return list;
	}
	
	@Override
	public String execute() throws Exception {
		User user1 = new User();
		user1.setUsername("zhangsan");
		user1.setPassword("123456");
		
		User user2 = new User();
		user2.setUsername("lisi");
		user2.setPassword("654321");
		
		list.add(user1);
		list.add(user2);
		return SUCCESS;
	}

}

从值栈中获取数据(采用第三种存放数据的方式)

  1. 获取字符串

  2. 获取对象

  3. 获取list集合(三种方式)

获取set和push方法设置的值


EL表达式为什么可以获取值栈的数据

  1. 底层对getAttribute方法进行了增强
  2. 首先在request域获取值,若获取到,则直接返回数据
  3. 若取不到,则在值栈中查找数据并放到域对象中去

ognl中%、#的使用

  1. #的使用
    1)获取context里面的数据(获取list集合的第三种方式)
    2)通过request域放置的数据

  2. %的使用
    1)struts中的表单标签<s:textfield></s:textfield>
    2)在struts2标签里面使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只有%之后才会识别

    3)实质生成的html代码
<input type="text" name="username" value="具体的值"/>