Struts2(三)--OGNL&值栈

一、OGNL

OGNL:OGNL 是 Object-Graph Navigation Language
的缩写,从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置 java 对象的属性 , 它旨在提供一个更高抽象度语法来对 java
对象图进行导航

1.1 OGNL在struts2环境的使用

  • 调用对象的方法

在jsp页面中使用对象的防范,需添加struts2的tags标签

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
   <%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<h1>OGNL在struts2环境中的入门</h1>
<h3>调用对象的方法</h3>
<s:property value="'struts'.length()"/>
</body>
</html>

结果如下:
在这里插入图片描述

  • 调用对象的静态方法

@类名@方法名

默认关闭访问静态方法,需开启常量。

struts.xml

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

<struts>
	<!-- 配置struts2的常量 -->
	<!-- 开启静态方法访问-->
	<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
</struts>

jsp页面

<h3>调用对象的静态方法</h3>
<s:property value="@java.lang.Math@random()"/>

结果如下:
在这里插入图片描述

二、值栈

2.1 值栈(ValueStack):

在struts2中使用ONGL将请求Action的参数封装为对象存储到值栈中,并通过OGNL表达式读取值栈中的对象属性

值栈贯穿整个Action的生命周期。Action一旦创建,框架就会创建一个ValueStack对象。struts2使用OGNL将请求Action的参数封装为对象存储在值栈中,并通过OGNL表达式读取值栈中的对象属性值

2.2 值栈的内部结构

值栈内部有两个区域:

  • root:

真实对象为CompoundRoot,继承ArrayList

root放置的是Object对象

获取root中的数据不需要加#

操作值栈一般为操作root区

  • context:

真实对象为OGNLContext,实现了Map接口

context中存有root的引用,还有request、session、application、parameters、attr的web开发对象引用

获取context中的数据需要加#

内部结构查看:

Action类:

package com.struts2.valuestack.demo01;

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

/*
 * ValueStack的内部结构
 */
public class ValueStackDemo01 extends ActionSupport{

	@SuppressWarnings("unused")
	@Override
	public String execute() throws Exception {
		//获得值栈
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		return SUCCESS;
	}
}

success.jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>查看值栈内部结构</h1>
<s:debug></s:debug>
</body>
</html>

结果如下:

在这里插入图片描述
2.3 值栈与ActionContext的关系

创建ActionContext时,创建了ValueStack对象,将ValueStack对象传递给了ActionContext对象,所有可以通过ActionContext获得ValueStack对象

所以在 Struts(二) 可以通过ActionContext对象访问Servlet API,因为在ActionContext内部有值栈,而值栈内部有常见的web开发对象的引用。

2.4 获得值栈

可以通过两种方式,Action初始化时,valueStack也被存入request中一份

package com.struts2.valuestack.demo01;

import org.apache.struts2.ServletActionContext;

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

/**
 * 获取值栈对象
 * @author cf
 *
 */
public class ValueStackDemo02 extends ActionSupport {

	@Override
	public String execute() throws Exception {
		//通过ActionContext获得
		ValueStack valueStack1 = ActionContext.getContext().getValueStack();
		
		//通过request获得
		ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
		
		//判断是否是同一个
		System.out.println(valueStack1 == valueStack2);
		return NONE;
	}
}

结果如下:

在这里插入图片描述
2.5 操作值栈

  • 通过在Action类中的get方法存入数据

默认情况下,Action对象被亚茹值栈,其属性也被压入值栈

Action类:

package com.struts2.valuestack.demo01;

import com.opensymphony.xwork2.ActionSupport;
import com.struts2.domain.Product;

/**
 * 操作ValueStack
 * @author cf
 *
 */
public class ValueStackDemo03 extends ActionSupport{
	private Product product;

	public Product getProduct() {
		return product;
	}

	@Override
	public String execute() throws Exception {
		
		//向ValueStack中存值
		product = new Product("iphoneXR",new Double(4999),"手机数码");
		
		return SUCCESS;
	}
}

结果:
在这里插入图片描述
在jsp中使用property获取值

<s:property value="product.name"/>
<s:property value="product.price"/>
<s:property value="product.category"/>

结果如下:

在这里插入图片描述

  • 通过值栈中的方法存入数据

set后压入值栈,取出的属性只能是最靠近栈顶的属性,因此name属性被覆盖

package com.struts2.valuestack.demo01;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import com.struts2.domain.Product;

/**
 * 调用值栈中的方法操作值栈
 * @author cf
 *
 */
public class ValueStackDemo04 extends ActionSupport{

		@Override
		public String execute() throws Exception {
			//获得值栈对象 
			ValueStack valueStack = ActionContext.getContext().getValueStack();
			//pusth(Obejct obj);对象   set(String key, Object(obj));集合
			Product product = new Product("iphoneXR",new Double(4999),"手机数码");
			valueStack.push(product);
			
			valueStack.set("name", "iphoneXS");
			
			return SUCCESS;
		}
   }

jsp页面:

<s:property value="name"/>
<s:property value="price"/>
<s:property value="category"/>

结果:
在这里插入图片描述
set压入的map在栈顶
在这里插入图片描述
2.6 获取值栈中的数据

使用OGNL表达式来取值

Action类存值:

package com.struts2.valuestack.demo01;

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

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.struts2.domain.Product;

/**
 * 获取值栈的数据
 * @author cf
 *
 */
public class ValueStackDemo05 extends ActionSupport{

	@Override
	public String execute() throws Exception {
		//向值栈中保存对象
		Product product = new Product("iphoneXR",new Double(4999),"手机数码");
		ActionContext.getContext().getValueStack().push(product);
		//向值栈中保存集合
		List<Product> list = new ArrayList<Product>();
		list.add(new Product("iphoneXS",new Double(6999),"手机数码"));
		list.add(new Product("iphoneXS MAX",new Double(8999),"手机数码"));
		list.add(new Product("P30",new Double(3999),"手机数码"));
		ActionContext.getContext().getValueStack().set("list", list);
		//向Context中保存数据,即向作用域中保存数据
		ServletActionContext.getRequest().setAttribute("name", "request中的数据");
		ServletActionContext.getRequest().getSession().setAttribute("name", "session中的数据");
		ServletActionContext.getServletContext().setAttribute("name", "application中的数据");
		
		return SUCCESS;
	}
}

success.jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>查看值栈内部数据</h1>
<s:debug></s:debug>

<%-- <s:property value="product.name"/> --%>
<%-- <s:property value="product.price"/> --%>
<%-- <s:property value="product.category"/> --%>

<%-- <s:property value="name"/> --%>
<%-- <s:property value="price"/> --%>
<%-- <s:property value="category"/> --%>

<h3>取对象中的值</h3>
<s:property value="name"/>
<s:property value="price"/>
<s:property value="category"/>

<h3>取list中的值</h3>
<s:property value="list[0].name"/>
<s:property value="list[0].price"/>
<s:property value="list[0].category"/><br>
<s:property value="list[1].name"/>
<s:property value="list[1].price"/>
<s:property value="list[1].category"/><br>
<s:property value="list[2].name"/>
<s:property value="list[2].price"/>
<s:property value="list[2].category"/><br>

<h3>取Context中的值, 需使用#号</h3>
<s:property value="#request.name"/><br>
<s:property value="#session.name"/><br>
<s:property value="#application.name"/><br>

</body>
</html>

结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值