OGNL

ONGL

一.ONGL基本介绍:
OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。这样可以更好的取得数据。
2 OgnlContext(ongl上下文)其实就是Map (教室、老师、学生)
map 教室
OgnlContext=根对象(1)+非根对象(N)
老师:跟对象 1
学生:非根对象 n
非根对象要通过"#key"访问,根对象可以省略"#key"
二.用法
OGNL是通常要结合Struts 2的标志一起使用。主要是#、%和$这三个符号的使用。使用方法如下:
OGNL_第1张图片
访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性: 名称 作用 例子
parameters 包含当前HTTP请求参数的Map #parameters.id[0]作用相当于request.getParameterValues(“id”).get(0);

request 包含当前HttpServletRequest的属性(attribute)的Map #request.userName相当于request.getAttribute(“userName”)

session 包含当前HttpSession的属性(attribute)的Map #session.userName相当于session.getAttribute(“userName”)

application 包含当前应用的ServletContext的属性(attribute)的Map #application.userName相当于application.getAttribute(“userName”)

attr 用于按request > session > application顺序访问其属性(attribute) #attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止
三.案例
1.根对象取值和非根对象取值的现象,以及OGNL取值和赋值的案例
实体类:

package com.test;

public class Employee {
	private String name;

	private Address address;

	private Integer salary;

	public Employee() {
		super();
	}

	public Employee(String name, Integer salary) {
		super();
		this.name = name;
		this.salary = salary;
	}

	public Integer getSalary() {
		return salary;
	}

	public void setSalary(Integer salary) {
		this.salary = salary;
	}

	public String getName() {
		return name;
	}

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

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	@Override
	public String toString() {
		return "Employee [name=" + name + ", address=" + address + ", salary=" + salary + "]";
	}

}

package com.test;

public class Student {
	private String name;

	private String number;

	public Student() {
		super();
	}

	public Student(String name, String number) {
		super();
		this.name = name;
		this.number = number;
	}

	public String getName() {
		return name;
	}

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

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", number=" + number + "]";
	}

}

测试类:

package com.test;

import ognl.OgnlContext;
import ognl.OgnlException;

public class Demo1 {

	/**
	 * @param args
	 * @throws OgnlException
	 */
	public static void main(String[] args)  {
		Employee e = new Employee();
		e.setName("小李");

		Manager m = new Manager();
		m.setName("张经理");

		// 创建OGNL下文,而OGNL上下文实际上就是一个Map对象
		OgnlContext ctx = new OgnlContext();

		// 将员工和经理放到OGNL上下文当中去
		ctx.put("employee", e);
		ctx.put("manager", m);
		ctx.setRoot(e);// 设置OGNL上下文的根对象

		/** ********************** 取值操作 *************************** */
		// 表达式name将执行e.getName(),因为e对象是根对象(请注意根对象和非根对象表达式的区别)
		String employeeName = (String) OnglExpression.getValue("name", ctx, e);
		System.out.println(employeeName);

		// 表达式#manager.name将执行m.getName(),注意:如果访问的不是根对象那么必须在前面加上一个名称空间,例如:#manager.name
		String managerName = (String) OnglExpression.getValue("#manager.name",
				ctx, e);
		System.out.println(managerName);

		// 当然根对象也可以使用#employee.name表达式进行访问
		employeeName = (String) OnglExpression.getValue("#employee.name", ctx,
				e);
		System.out.println(employeeName);

		/** ********************** 赋值操作 *************************** */
		OnglExpression.setValue("name", ctx, e, "小明");
		employeeName = (String) OnglExpression.getValue("name", ctx, e);
		System.out.println(employeeName);

		OnglExpression.setValue("#manager.name", ctx, e, "孙经理");
		managerName = (String) OnglExpression.getValue("#manager.name", ctx, e);
		System.out.println(managerName);

		OnglExpression.setValue("#employee.name", ctx, e, "小芳");
		employeeName = (String) OnglExpression.getValue("name", ctx, e);
		System.out.println(employeeName);
	}

}

得到结果如下:
OGNL_第2张图片
2.OGNL向ValueStack压栈
2.1 值栈
先进后出的数据结构,弹夹 push/pop
2.2 为什么要使用ValueStack作为根对象
放到值栈中的对象都可视为根对象

package com.test;

import org.apache.struts2.ServletActionContext;

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

public class Demo7 {
	/**
	 * 
	 * 值栈的使用
	 * 
	 */
	public static void main1(String[] args) {
		// 栈:表示一个先进后出的数据结构
	/*	ValueStack vs = new OgnlValueStack();*/
		ValueStack vs=ServletActionContext.getContext().getValueStack();
		// push方法把项压入栈顶
		vs.push(new Employee("zs", 22));
		vs.push(new Employee("ls", 22));
		vs.push(new Employee("ww", 22));

		// pop方法移除栈顶对象并作为此函数的值返回该对象
		Employee e = (Employee) vs.pop();
		System.out.println(e.getName());
		e = (Employee) vs.pop();
		System.out.println(e.getName());
		e = (Employee) vs.pop();
		System.out.println(e.getName());
	}

	/**
	 * 此例用于模拟struts2的值栈计算过程
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		//ValueStack vs = new OgnlValueStack();
		ValueStack vs=ServletActionContext.getContext().getValueStack();
		vs.push(new Employee("张雇员", 2000));// 1
		vs.push(new Student("小明同学", "s001"));// 0
		System.out.println(vs.findValue("name"));
		System.out.println(vs.findValue("salary"));

		ActionContext ac = ActionContext.getContext();
	}
}

之后配置Struts-sy.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>

	<package name="sy" extends="base" namespace="/sy">
	<action name="stack_*" class="com.test.DemoAction" method="{1}">
	<result name="rs">/rs.jsp</result>
	</action>
	</package>
</struts>

前台代码:

<%@ 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>
<h3>OGNL</h3>
<a href="${pageContext.request.contextPath }/sy/stack_test1.action">测试ongll</a>
<a href="${pageContext.request.contextPath }/sy/stack_test2.action">测试ongl2</a>
</body>
</html>

测试结果
ongl1:
在这里插入图片描述
ongl2:
在这里插入图片描述

你可能感兴趣的:(OGNL)