Struts2(三)之值栈和OGNL表达式

之前我们做的查询列表用的是EL和JSTL来完成的,这样并不好,因为struts2里面有自己的表达式语言和存取值的方式,下面就来看一下。

OGNL的概述

什么是OGNL?
在这里插入图片描述OGNL:对象图导航语言,是一门功能强大的表达式语言。
OGNL的功能或作用:
Struts2默认的表达式语言就是OGNL,他支持:
1.对象方法的调用
2.类静态方法调用和值访问
3.赋值操作和表达式串联
4.访问ActionContext和OgnlContext数据
5.操作集合对象等

OGNL的三要素:
1.表达式(Expression) 核心,做什么,规定了操作类型和内容;
2.根对象(Root Object) 对谁操作,以任意一个对象为根,通过OGNL可以访问与这个对象关联的其他对象;
3.上下文环境(Context),在哪里进行,Context是一个Map类型对象,在表达式中访问Context中的对象,需要用“#对象名称”的形式。

OGNL的入门
  • OGNL访问对象的方法
package com.wangshi.struts.ognl;

import org.junit.Test;

import ognl.Ognl;
import ognl.OgnlContext;

/**
 * @author wanghaichaun
 *OGNL的入门
 */
public class OgnlDemo01 {
	
	@Test
	//ognl调用对象的方法
	public void demo01() throws Exception {
		//获得上下文Context
		OgnlContext context = new OgnlContext();
		//得到根对象
		Object root = context.getRoot();
		//获取值 'helloworld'.length()就是表达式,结果是 10
		Object obj = Ognl.getValue("'helloworld'.length()",context, root);
		System.out.println(obj);
		
	}
}

  • 访问对象的静态方法,执行表达式:@类名@方法名
	@Test
	//访问对象的静态方法
	public void demo02() throws Exception{
		
		//获取context 上下文
		OgnlContext context = new OgnlContext();
		//得到根对象
		Object root = context.getRoot();
		//取值,执行表达式:@类名@方法名
		Object obj = Ognl.getValue("@java.lang.Math@random()",context, root);
		System.out.println(obj);
	}
	
  • OGNL获取Root数据
@Test
	//OGNL获取数据
	public void demo03() throws OgnlException{
		//获得Context
		OgnlContext context = new OgnlContext();
		
		//在User类中获取ognlcontext中的数据:
		//获得根对象
		User user = new User("啦啦啦","12345");
		context.setRoot(user);
		//执行表达式
		Object username = Ognl.getValue("username",context, context.getRoot());
		Object password = Ognl.getValue("password",context, context.getRoot());
		System.out.println(username+"==="+password);
		
	}
  • OGNL获取context数据
	@Test
	//OGNL获取context数据
	public void demo04() throws OgnlException{
		//获得Context
		OgnlContext context = new OgnlContext();
		//得到根
		Object root = context.getRoot();
		//获取值
		context.put("username", "呦西");
		//执行表达式
		Object obj = Ognl.getValue("#username",context, root);
		System.out.println(obj);
		
	}

OGNL独立的表达式:
Java环境下入门
Struts2环境下入门
jsp页面并且配置struts2环境,静态方法访问在struts2中默认是关闭的,记得在default.properyies中开启

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s"  uri="/struts-tags"%>
<!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>
<h1>OGNL在Struts2环境中的入门</h1>
<s:property value="'struts'.length()"/>

<h1>调用静态的方法</h1>
<!-- 静态方法访问在struts2中默认是关闭的。开启了一个常量 -->
<s:property value="@java.lang.Math@random()"/>
</body>
</html>
值栈的概述

在这里插入图片描述
ValueStack:

	是一个接口,实现类OgnlValueStack;
	是数据的中转站,贯穿了整个Action,有一个Action的实例,就会创建一个ValueStack对象。

值栈的内部结构:

	ValueStack中有两个主要的区域:
	Root	:CompoundRoot,就是一个ArrayList,里面一般放置对象。获取Root的数据不需要加#。
	Context	:OgnlContext,就是一个Map,里面放置是web开发的常用的对象数据的引用。获取Context的数据需要加#。

在这里插入图片描述

package com.wangshi.struts.valuestack;

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

/**
 * @author wanghaichaun
 *ValueStack的内部结构
 */
public class ValueStackDemo01 extends ActionSupport {
	
	@SuppressWarnings("unused")
	@Override
	public String execute() throws Exception {
		
		//获得值栈
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		
		return SUCCESS;
	}

}

Context :OgnlContext的上下文,存储的引用:

	parameters:map中包含的当前请求的请求参数;
	request:map中包含当前request对象中的所有属性;
	session:map中包含当前session对象中的所有属性;
	application:map中包含当前application对象中的所有属性;
	attr:该map 按顺序来检索某个属性:request,session,application

在这里插入图片描述
所说的操作值栈,通常就是值操作的ValueStack中的root区域.

ActionContext和值栈关系

ServletContext:Servlet的上下文。
ActionContext:Action的上下文。

	1.通过源码查看到:当请求过来时,执行过滤器中的dofilter方法,在这个方法中创建ActionContext,
	在创ActionContext过程中.创建ValueStack对象,将ValueStack对象传递给ActionContext对象,
	所以可以通过ActionContext获取值栈对象.
	
	2.ActionContext对象之所以能够访问Servlet的api(访问的是域对象的数据),因为在其内部有值栈的引用.
获得值栈对象

通过ActionContext获取

//1.通过ActionContext获得值栈
ValueStack valueStack = ActionContext.getContext().getValueStack();
		

通过request获取

//2.通过request对象获得
		ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest()
				.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
操作值栈【向值栈中存入数据】

两种:
*在Action 中提供属性的get方法的方式
默认情况下,将action对象压入到值栈,action的属性也会在值栈中。

package com.wangshi.struts.valuestack;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import com.wangshi.struts.entity.User;

/**
 * @author wanghaichaun
 *在Action 中提供属性的get方法的方式,操作valueStack
 */
public class ValueStackDemo03 extends ActionSupport {
	
	private User user;
	
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	@Override
	public String execute() throws Exception {
		//向valuestack中存值
		 user = new User("啊你有","123");

		return SUCCESS;
	}

}

*使用ValueStack 中本身的方法的方式

package com.wangshi.struts.valuestack;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
import com.wangshi.struts.entity.User;

/**
 * @author wanghaichaun
 *方式二:使用ValueStack 中本身的方法的方式获取值
 */
public class ValueStackDemo04 extends ActionSupport {
	
	@Override
	public String execute() throws Exception {
	
		//获取值栈对象
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		//存值
		User user = new User("看看","222");
		//现在user在栈顶的位置
		valueStack.push(user);

		valueStack.set("username", "东东");//创建的是一个Map集合,将map压入到栈中;
		valueStack.set("password", "123321");

		return SUCCESS;
	}

}

编写jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>
<h1>查看值栈的内部结构</h1>
<s:debug></s:debug>

<!-- 方式一:利用Action在值栈中的特性获取值 -->
<s:property value="user.username"/>
<s:property value="user.password"/>

<!-- 方式二:使用ValueStack 中本身的方法的方式获取值 -->
<s:property value="username"/>
<s:property value="password"/>
</body>
</html>

记得到struts.xml中配置

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

	<package name="demo01" extends="struts-default" namespace="/">
		<action name="ValueStackDemo01" class="com.wangshi.struts.valuestack.ValueStackDemo01">
			<result >/demo01/success.jsp</result>
		</action>
		
		<action name="ValueStackDemo02" class="com.wangshi.struts.valuestack.ValueStackDemo02">
		</action>
		
		<action name="ValueStackDemo03" class="com.wangshi.struts.valuestack.ValueStackDemo03">
			<result >/demo01/success.jsp</result>
		</action>
		
		<action name="ValueStackDemo04" class="com.wangshi.struts.valuestack.ValueStackDemo04">
			<result >/demo01/success.jsp</result>
		</action>
	</package>

</struts>
获取值栈的数据
获取Root中的数据,不需要加#
  • 保存一个对象,获取ValueStack中的数据
    在这里插入图片描述
    在这里插入图片描述
  • 保存一个list集合,获取ValueStack中的数据
获Context中的数据,需要加#

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
OGNL获取:<s:property value=”…”/>

EL获取值栈的数据

底层对Request对象的request.getAttribute(“”)方法进行了增强;

ONGL特殊字符

#号
获取context数据
在这里插入图片描述
构建map集合
在这里插入图片描述

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!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>
<h1>#号的用法</h1>
<h3>获取Context的数据</h3>
<%
	request.setAttribute("name", "拉丝");
%>
<s:property value="#request.name "/>

<h3>用于构建一个map集合:使用struts的UI标签的时候</h3>

 <h3>list的集合</h3>
<s:iterator var="i"  value="{'aa' ,'bb' ,' cc'}">
	<s:property value="i"/>---<s:property value="#i"/><br>
</s:iterator>
 <h3>map的集合</h3>
<s:iterator value="#{'aaa':'111', 'bbb':'222','ccc':'333'}"  var="entry">
	<s:property value="key"/>-----<s:property value="value"/><br>
	<s:property value="#entry.key"/>-----<s:property value="#entry.value"/><br>
</s:iterator>
<s:radio list="#{'1':'男','2':'女' }" name="sex"></s:radio>
<s:debug></s:debug>
</body>
</html>

%号
强制解析OGNL

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>
<%
	request.setAttribute("name", "王者归来");
%>
<h3>%号的用法:强制解析</h3>
<s:textfield name="name"  value="%{#request.name}" />
<h3>%号的用法:不强制解析</h3>
<s:property value="%{'#request.name'}"/>

</body>
</html>

$号
在配置文件中使用OGNL

  • 属性文件
    国际化地方:

      *message zh CN.properties
      user.login=登录
      user.welcome=欢迎,${#session.user.username}
    
      *message en US.properties
      user.login=Login
      user.welcome=welcome,${#session.user.username}
    
  • XML文件
    文件下载:

      配置
      <action name="download" class="xxx.DownloadAction">
      	<result type="stream">
      		<param name="Context-Disposition">文件类型</param>
      		<param name="Context-Disposition">attachment;filename=${文件名}</param>
      	</result>
      </action>
    

----------------------------------今天就了解到这里,有写的不好的地方请大家多多包涵!☻
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值