Struts2【OGNL、valueStack】就是这么简单
什么是OGNL表达式?
OGNL是Object Graphic Navigation Language 是操作对象属性的开源表达式。 Struts2框架使用OGNL作为默认的表达式语言。
为什么我们学习OGNL
在学习JSP的时候,我们已经学习过了EL表达式。EL表达式用起来也十分简单...我们在Struts2框架中也是可以使用EL表达式的...那么OGNL表达式好在哪里呢??
- 支持对象方法调用,如xxx.doSomeSpecial()
- 支持类静态的方法调用和值访问,表达式的格式【例如:"@@floor(10.9)"就是调用Math.floor()的方法了】
- 支持赋值操作和表达式串联【这个其实EL表达式也能做】
- 访问OGNL上下文(OGNL context)和ActionContext
- 操作集合对象【EL只能遍历集合,OGNL可以创建集合】
OGNL是Struts2的默认表达式语言,OGNL是配搭Strut2的标签使用的..我们学习了OGNL表达式,就可以更好地理解Struts2标签的运行以及Struts2内部的存储结构.
valueStack对象
在讲解OGNL表达式之前,我们先来看看valueStack对象...valueStack是Struts2数据存储的核心...我们首先要知道数据是怎么存的,存到哪里,然后才讲解OGNL表达式是怎么取出数据的。
valueStack也被称作值栈对象..
- 当用户访问Action,都会创建一个Action对象,ActionContext对象、valueStack对象..
- Struts2把Action对象放进valueStack对象之中。
- 将valueStack放进request域中,传入JSP页面(key: struts.valueStack)
- JSP页面就可以使用OGNL表达式获取值栈中的数据了!
获取valueStack对象
- 在Action中我们可以手动获取值栈对象,有两种方式获取:
	//获取值栈对象的2种方式
	private void getVs() {
		// 获取值栈对象,方式1:
		HttpServletRequest request = ServletActionContext.getRequest();
		ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack");
		// 获取值栈对象,方式2:
		ActionContext ac = ActionContext.getContext();
		ValueStack vs2 = ac.getValueStack();
		System.out.println(vs1 == vs2);//true
	}
valueStack内部存储结构
上面已经说了,用户访问Action时,会创建Action对象,valueStack对象。Struts2内部会将Action对象存到valueStack对象之中...那么valueStack的存储结构是什么样的呢???我们来看看
CompoundRoot
Action对象和Action的成员属性等值都是存到CompoundRoot下的.该CompoundRoot继承着ArrayList,因此它是List结构的
	public class CompoundRoot extends ArrayList {}
OgnlContext
OgnlContext对象存储着相关的域对象:request、response、session等数据,实现Map集合,是Map结构..
为了让request、response等域对象可以存储多个值,值也是使用Map结构...
public class OgnlContext implements Map {}
小总结
CompoundRoot保存着这样的数据:
- Action对象以及Action对象的成员属性数据
- 使用ValueStack对象.push()进去的数据
- 使用ValueStack对象.set()进去的数据
- 其他代理对象的数据
OgnlContext保存着这样的数据:
- 维护了CompoundRoot中所有的数据
- request、response等域对象所有的数据
OGNL表达式取值
- Struts2会将valueStack对象封装进request对象域中,传入JSP页面。
- valueStack存储着OgnlContext对象。
- OgnlContext对象维护了CompoundRoot对象的数据
- CompoundRoot存储着Action等数据
也就是说通过OgnlContext对象可以获取大部分我们需要的数据了。
那么OGNL表达式是怎么取出OgnlContext对象中数据的呢??下面我们通过硬编码的方式来讲解:
	/**
	 * 1. Ognl表达式语言语言取值,取非根元素的值,必须用#号
	 * @throws Exception
	 */
	@Test
	public void testOgnl() throws Exception {
		// 创建一个Ognl上下文对象
		OgnlContext context = new OgnlContext();
		// 放入数据
		User user = new User();
		user.setId(100);
		user.setName("Jack");
		// 【往非根元素放入数据, 取值的时候表达式要用"#"】
		context.put("user", user);
		// 获取数据(map)
		// 先构建一个Ognl表达式, 再解析表达式
		Object ognl = Ognl.parseExpression("#user.name");
		Object value = Ognl.getValue(ognl, context, context.getRoot());
		System.out.println(value);
	}
	/**
	 * 2. Ognl表达式语言语言取值,取根元素的值,不用带#号
	 * @throws Exception
	 */
	@Test
	public void testOgn2() throws Exception {
		// 创建一个Ognl上下文对象
		OgnlContext context = new OgnlContext();
		// 放入数据
		User user = new User();
		user.setId(100);
		user.setName("Jack");
		// 【往根元素放入数据】
		context.setRoot(user);
		// 获取数据(map)
		// 先构建一个Ognl表达式, 再解析表达式
		Object ognl = Ognl.parseExpression("address.province");
		Object value = Ognl.getValue(ognl, context, context.getRoot());
		System.out.println(value);
	}
也就是说,JSP页面中取出数据的时候,它会先构建一个OGNL表达式,再解析表达式
- 如果是CompoundRoot类的数据,表达式不需要带#号
- 如果不是CompoundRoot类的数据,表达式需要带#号
例子:
  	<!-- 页面: 必须要拿到ValueStack -->
     <br/>1. 取根元素的值<br/>
     <s:property value="user.id"/>
     <s:property value="user.name"/>
     <s:property value="user.address"/>
     <s:property value="user.address.city"/>
     <s:property value="user.address.province"/> 
      <br/>2. 取非根元素的值<br/>
      <s:property value="#request.cn"/>
      <s:property value="#session.Session_data"/>
      <s:property value="#application.Application_data"/>    <br/>
      <!-- 自动找request/session/application,找到后立刻返回 -->
      <s:property value="#request_data"/>
      <s:property value="#attr.Session_data"/>
      <s:property value="#attr.Application_data"/>  <br/>
      <!-- 获取请求的参数数据 -->
      <s:property value="#parameters.userName"/>
     <!-- struts的调试标签:可以观测值栈数据 -->
     <s:debug></s:debug>
OGNL对静态方法的调用
	/**
	 * 3.Ognl对 静态方法调用的支持
	 * @throws Exception
	 */
	@Test
	public void testOgn3() throws Exception {
		// 创建一个Ognl上下文对象
		OgnlContext context = new OgnlContext();
		// Ognl表单式语言,调用类的静态方法
		//Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
		// 由于Math类在开发中比较常用,所以也可以这样写
		Object ognl = Ognl.parseExpression("@@floor(10.9)");
		Object value = Ognl.getValue(ognl, context, context.getRoot());
		System.out.println(value);
	}
OGNL创建集合
    <br/>一、.构建 list集合</br>
    <s:iterator var="str" value="{'a','b'}">
    	<s:property value="#str"/>
    </s:iterator>
     <br/>一、.构建 map集合</br>
     <s:iterator var="en" value="#{'cn':'China','usa':'America'}">
     	<s:property value="#en.key"/>
     	<s:property value="#en.value"/>  <br/>
     </s:iterator>
构建Map集合的时候,需要使用#号
OGNL 几个特殊的符号#
#获取非根元素值  、 动态都建map集合
$  在配置文件取值
%  提供一个ognl表达式运行环境
<body>
  	 <br/>获取request域数据<br/>
  	 <!-- property 标签是对象类型的标签,默认支持ognl表达式, 会从根元素去China名称对应的值 -->
  	 <s:property value="China"/>		<br/>
  	 <!-- 如果直接赋值,需要用单引号 -->
  	 <s:property value="'China'"/>		<br/>
  	 <s:property value="%{#request.cn}"/>		<br/>
  	 <!-- 值类型的标签,value值默认就是值类型,不支持ognl表达式 -->
  	 国家:<s:textfield name="txtCountry" value="%{#request.cn}"></s:textfield>
  </body>
如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y
Struts2【OGNL、valueStack】就是这么简单的更多相关文章
- struts2 OGNL ValueStack概念理解 # % $ 的区别
		http://blog.csdn.net/tjujacob/article/details/8117659 —————————————————————————————————————————————— ... 
- Struts2(Ognl)
		OGNL(Object-Graph Navigation Language)全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整 ... 
- Struts2:ValueStack
		一.ValueStack 1 .ValueStack是一个接口,在struts2中使用OGNL(Object-Graph Navigation Language)表达式实际上是使用 ... 
- 浅析=======Struts2之==========valueStack
		今天刚学习了struts2的valueStack,在这里把自己学到的做个分享,说道valueStack就不得不提OGNL表达式=== struts2工作流程 1.OGNL(Object Graph N ... 
- Struts2的配置和一个简单的例子
		Struts2的配置和一个简单的例子 笔记仓库:https://github.com/nnngu/LearningNotes 简介 这篇文章主要讲如何在 IntelliJ IDEA 中使用 Strut ... 
- Struts2中ValueStack结构和总结
		[ValueStack和ActionContext的关系] 首先,从结构上来看ValueStack是ActionContext的一个组成部分,是对ActionContext功能的扩展.ActionCo ... 
- 使用Struts2和jQuery EasyUI实现简单CRUD系统(转载汇总)
		使用Struts2和jQuery EasyUI实现简单CRUD系统(一)——从零开始,ajax与Servlet的交互 使用Struts2和jQuery EasyUI实现简单CRUD系统(二)——aja ... 
- java框架之Struts2(3)-OGNL&ValueStack
		OGNL 概述 OGNL 是 Object-Graph Navigation Language 的缩写,它是一种第三方的.功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用 ... 
- struts2重点——ValueStack和OGNL
		一.值栈(ValueStack) 1.实现类:OGNLValueStack 2.对象栈:CompoundRoot(针对的是类级别的) (1)继承自 ArrayList —— 先进后出 (2)提供了栈的 ... 
- Struts2  OGNL表达式、ValueStack
		OGNL简介 OGNL,即Object-Graph Navigation Language,对象视图导航语言,是一种数据访问语言,比EL表达式更加强大: EL只能从11个内置对象中取值,且只能获取属性 ... 
随机推荐
- 分享一下自己写的一个vscode-leetcode答题插件
			0. 前言 春节这几天每天吃吃喝喝睡睡玩玩,突然发现明天就要上班了,吓得我虎躯一震. 春节结束之后,学生党们陆续开学,相信有许多同学马上就要在春季招聘中拼杀一番.想要收获心意的offer,当然免不了对 ... 
- 乞丐版servlet容器第1篇
			本系列参照pkpk1234大神的BeggarServletContainer,具体请访问:https://github.com/pkpk1234/BeggarServletContainer. 一步一 ... 
- Leetcode刷题C#版之 Median of Two Sorted Arrays
			题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ... 
- CocosCreator游戏开发---菜鸟学习之路(三)如何在CocosCreator中使用Pomelo
			PS(废话): 这段时间都在研究网易的Pomelo框架,作为新手小白,自然遇到了不少坑爹的事情.(当然也有可能是因为自己技术不过关的原因所以导致在很多基础的问题上纠结了很久.)网上也搜索了好久,但是基 ... 
- Go解析写死的json
			func TestAliAfpAdapter_AskAd_Banner(t *testing.T) { apiData := getApiData() apiData.ApiInfo.ApiPosit ... 
- 配置Nginx代理服务器
			nginx另一个使用的比较多的情况是作为代理服务器,代理服务器接收请求,然后把请求传递到代理服务器,nginx最后会提取代理服务器的回复,并把这些回复发送给客户端.我们将配置一个基本的代理服务器,图片 ... 
- 华为云照片的爬虫程序更新(python3.6)
			一.背景: 每年终都有一个习惯,就是整理资料进行归档,结果发现手机照片全备份在华为云里,在官网上找了一圈,没找到官方的pc工具用来同步照片. 于是找出上次写的程序,看看能不能爬到数据,然而……果然不好 ... 
- Asp.Net Core 基于QuartzNet任务管理系统
			之前一直想搞个后台任务管理系统,零零散散的搞到现在,也算完成了. 这里发布出来,请园里的dalao批评指导! 废话不多说,进入正题. github地址:https://github.com/YANGK ... 
- Servlet3.0+springmvc5+log4j2正确的开启姿势(WebLookUp)
			前言 java社区占据市场份额比较大的日志组件由log4j 1.×,到logback,再到整合后的升级版 log4j 2.×,有网友测试后据说log4j2的性能最NB.于是开始往自己的springmv ... 
- Mac下使用SSH(密钥)访问Github
			1,终端中输入:cd ~/.ssh 如果出现 -bash: cd: /Users/glamor/.ssh: No such file or directory,说明你之前没有用过.直接执行第二步. 如 ... 
