ognl和struts的传值的优先级

前言:上次与大家分享了SSH框架之Struts的知识,今天就接着之前的分享,今天要分享的知识是Ognl

码字不易,点个赞

转载请说明!

开发工具:eclipse


目录

OGNL是什么?

一、明确目标

        1、弄清楚之前遗留的问题(user中的uname属性有值,而Demo1Action中的uanme属性没有值?)        2、Struts的优先级

二、Struts的优先级

三、Ognl的特点

1、值栈是先进后出的特点

2、计数是从上至下的

四、解决上次的问题(user中的uname属性有值,而Demo1Action中的uanme属性没有值)


OGNL是什么?

OGNL的全称是Object Graph Navigation Language(对象图导航语言)

ognlContext(ognl上下文)其实就是Map(教室、老师、学生)

Map:教室

OgnlContext = 根对象(1)+ 非根对象(N)

老师: 根对象 1

学生 :非根对象  n

非根对象要通过"#key"访问,根对象可以省略"#key"

一、明确目标

        1、弄清楚之前遗留的问题(user中的uname属性有值,而Demo1Action中的uanme属性没有值?
        2、Struts的优先级

情景再现

在之前的demo1action界面中加一个uname属性,并且生成get和set方法。在demo1中再写set方法传值的代码

Demo1Action界面

package com.hpw.one.web;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;

import com.hpw.one.entity.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class Demo1Action extends ActionSupport implements ModelDriven<User>,ServletRequestAware,ServletResponseAware{
	
	private HttpServletRequest req;
	private HttpServletResponse resp;
	private User user1 = new User();
	private String uname;
	private String sex;
	private User user2;
	
	
	public String getUname() {
		return uname;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	
public User getUser1() {
		return user1;
	}

	public void setUser1(User user1) {
		this.user1 = user1;
	}

	public User getUser2() {
		return user2;
	}

	public void setUser2(User user2) {
		this.user2 = user2;
	}

public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

public String add() throws Exception {
	System.out.println("add方法...");
	return "bookEdit";
}

public String del() throws Exception {
	System.out.println("del方法...");
	return "bookEdit";
}

public String edit() throws Exception {
	System.out.println("edit方法...");
	return "bookEdit";
}

public String list() throws Exception {
	System.out.println("list方法...");
	System.out.println(user1);
	System.out.println(user2);
	System.out.println(sex);
	HttpServletRequest request = ServletActionContext.getRequest();
	request.setAttribute("age", 12);
	req.setAttribute("hobby", "ccc");
	return "bookEdit";
}

public User getModel() {
	return user1;
}

@Override
public void setServletResponse(HttpServletResponse arg0) {
   this.resp = arg0;	
}

@Override
public void setServletRequest(HttpServletRequest arg0) {
	this.req = arg0;
	
}



}

demo1界面

<a href="${pageContext.request.contextPath }/sy/demo1_list.action?uname=ognl">set方法传参</a><br> 

当我运行 Demo1界面,为什么user中的uname属性有值,而Demo1Action中的uanme属性没有值,这里涉及到了Struts的优先级

二、Struts的优先级

Struts的优先级与我们今天的题目有非常大的联系,struts中的jar包是依赖ognl,有着依赖关系,所以讲Struts的优先级时可以围绕着ognl的两大特点来进行分享。从而解决昨天遗留的问题

    导入帮助类

在demo1中我将小明设为根对象。其他的为非根对象,会进行一系列的替换值

package com.hpw.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);
	}

}

从结果可以看出,无论怎么替换值,根对象有且只有一个(和一个良好的xml文件的起其中一个特点是相同的) 

 

三、Ognl的特点

1、值栈是先进后出的特点

用一个案例解释

demo1

 
	public String ognl1() {
		// 栈:表示一个先进后出的数据结构
		ValueStack vs = ActionContext.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());
		return "bookEdit";
	}

 struts-sy.xml

 

运行结果如下

 Ognl的这一特点与List结合中的LinkedList的堆栈的特点是一样的

2、计数是从上至下的

同样的与讲上一特点用一个案列来讲解,有两个人物,一个是张雇员,薪资为2000,另一个是小明同学,编号为s001,我从中找出name和salary的值就验证了这一特点

demo1

public String ognl2() {
		ValueStack vs = ActionContext.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("salary2"));
		return "bookEdit";
	}

Student类 

package com.hpw.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 + "]";
	}

}

Employee 

package com.hpw.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 + "]";
	}

}

Ognl.jsp

<%@ 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/demo7_ognl1.action">值栈是符合先进后出的特点</a><br>
<a href="${pageContext.request.contextPath }/sy/demo1_ognl2.action">计数是从上至下的特点</a><br>
</html>

 运行结果如下

将两个人物装入一个容器时,小明同学在上面,张雇员在下面,计数的时候先要取出小明同学看有没有这个值,如果有就会把对应属性的值取出来,如果没有就会进行下一步,把一个人物取出来,看有没有这个值,同样的,有对应属性的值就会取出来,没有就会一直找,直到找到为止。取值的时候也体现出了ognl的特点一

四、解决上次的问题(user中的uname属性有值,而Demo1Action中的uanme属性没有值)

示意图

 示意图阐释: 在Demo1Action中,有一个user对象,以及uname这一个属性,而user对象是ModelDriven接口用来定义模型的,而uname这一属性是属于Demo1Action这一个类的。在最开始的时候,我创建Demo1Action这一个类时,就已经将Demo1Action这一个类装到的一个容器的底部,之后我再实现ModerDriven接口的时候,我同样将ModerDriven接口装进了刚刚那个容器里面,同理可得:映射出一个一模一样的容器,对应的属性就装到了容器里面(首先是Demo1Action对应的uname属性,其次是ModerDriven对应的user1对象),当我把uname=ognl这一属性值加入到容器中时,首先是计数是从上至下的和先进后出的特点,将ognl值加入到ModerDriven的uname属性中,Demo1Action的uname属性就没有值了,当运行ognl.jsp时,运行出的结果往往符合了Ognl的第一特点,先进后出的特点。自然而然的uname就为null。解释昨天遗留问题正好用Ognl的两大特点验证了

Ognl最重要的就是将其中的理论知识理解透彻是最重要的,记住两大特点是首要前提,之后理解是重要过程。希望能够帮助到大家,到这里就结束了,欢迎大佬指点  

猜你喜欢

转载自blog.csdn.net/weixin_56069070/article/details/120828765