struts2-day03 ongl quikcstart

一、概述

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。Struts2框架使用OGNL作为默认的表达式语言。相对于EL表达式来说它比较适合Struts2框架,本身的内置对象也做了很大的封装,可以作为开发了解。


二、quickstart

action.java


package cn.zjy.OGNL;

import java.io.Serializable;

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

public class OGNLtest1 extends ActionSupport implements Serializable {
 
	public String name;
	private String password;
	@Override
	public String execute() throws Exception {
		System.out.println("running");
		name="zhangsan";
		password="123";
		ActionContext actioncontext = ActionContext.getContext();
		actioncontext.put("name", "wangwu");
		actioncontext.put("username", "wangwu1");
		//存放于context上下文中
		//Returns the ActionContext specific to the current thread
		actioncontext.getSession().put("username","lisi" );
		// context.put(key, value); action中维护的一个map
		return SUCCESS;
	}
	

}
1.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <title>My JSP '`.jsp' starting page</title>
  <meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
  </head>
  
  <body>
	<s:property value="[0].name"/><br>
	<s:property value="username"/><br/>
	
	
	
	<!-- valueStack中的栈顶action 中的 name 属性  如果找不到 则会去寻找context中的 name-->
	<s:property value="#parameters.username[0]"/>
	<s:property value="#session.username"/>
	
	<s:property value="#session.name"/>
	<!-- 其余都需要加引用范围 -->
	<s:debug></s:debug>
	
	
	<!-- 使用el表达式 -->
	${name}<br/>
	${username}<br/>
	<!-- el表达式也可以访问action中的属性  struts属性中封装了其 方法-->
	
	${requestScope.username}<br/>
	
	${requestScope.name}<br/>
	<!-- request - valuestack(action) - actioncontext 这里struts2 框架对request已经包装  先使用request的name-->
	
	${sessionScope.username}<br/>
	${paramValues.a}
	<!-- http://127.0.0.1:8080/struts2-day03/ognl1/ognl1.action?a=1&a=2 -->
 </body>
</html>


结果显示


可以看到如同el表达式,一样,ognl的内置对象显示了在action中包装的属性,

quickstat之后看不懂的地方可以归纳为以下两点
一、
ActionContext actioncontext = ActionContext.getContext();
actioncontext.put("name", "wangwu");
actionContext是什么,内部是一个什么样的结构
二、
<s:property value="#parameters.username[0]"/> 是一种什么样的机制来显示,和el表达式有什么相似之处


三、原理概述

接下来我们先来了解一下,ActionContext中一个叫做上下文的概念,
        Ognl有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图
      
  

  当struts接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。

      了解了Context中的结构,我们了解一下其使用
  
      访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session
     
     另外OGNL会设定一个根对象(root对象),在struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。
   在Struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想象的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用它存放一组对象。

    在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。



   注意:Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:property value=“name”/>

    由于ValueStack(值栈)是Struts2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:
${foo}//获得值栈中某个对象的foo属性。
   
   如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀
   application对象:用于访问ServletContext,例如#application.userName或者#application[‘userName’],相当于调用ServletContext的getAttribute(“username”)。
   
    session对象:用来访问HttpSession,例如#session.userName或者#session[‘userName’],相当于调用session.getAttribute(“userName”)。

    request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request[‘userName’],相当于调用request.getAttribute(“userName”)。
   
    parameters对象:用与访问HTTP的请求参数,例如#parameters.userName或者#parameters[‘userName’],相当于调用request.getParameter(“username”)。
    
     attr对象:用于按pagerequestsessionapplication顺序访问其属性。

    看了以上一大段文字其实归纳起点就一点,el表达式中的11大内置对象在ognl表达式中换了个面孔,多了一个context ,它里面维护了session,application,request等相关对象,如果需要访问action中放在对应map中是属性,需要#对应范围来进行引用。
 
   当然 上面的式子里面有一个特殊的例子 我们这里来重点看一下

    action有自带属性name ,通过上面的例子我们可以直接用<s:property value="[0].name"/><br>来使用,但是 actioncontext.put("username", "wangwu1");到底是放在了哪里了?

看一张图<s:debug></s:debug>


很明显,他放在了context维护的那个map中,这样我们怎么访问呢?

<s:property value="username"/><br/>
<!-- valueStack中的栈顶action 中的 username 属性  如果找不到 则会去寻找context中的 username-->

接下来我们在看看el表达式


<!-- 使用el表达式 -->
${name}<br/>
${username}<br/>
<!-- el表达式也可以访问action中的属性  struts属性中封装了其 方法 如果找不到 则会去寻找context中的 name-->
${requestScope.name}<br/>
${requestScope.username}<br/>
 同样的el表达式也可以达到刚才的效果,其中比较特殊的就是request,他也可以访问action ->context属性

原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:
public class StrutsRequestWrapper extends HttpServletRequestWrapper{
public StrutsRequestWrapper(HttpServletRequest req){
super(req);
}
public Object getAttribute(String s){
…
ActionContext ctx = ActionContext.getContext();
Object attribute = super.getAttribute(s);//先从request范围获取属性值
if(ctx!=null){
if(attribute==null){//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
…
ValueStack stack = ctx.getValueStack();
attribute = stack.findValues(s);
…
}
}
return attribute;
}
}

看完了上述几点,差不多ognl 表达式的原理已经摸的差不多了,接下来就是熟练的问题了。

四、标签使用

既然ognl标签差不多已经入门,那么我们就来用几个例子来熟悉一下

一、创建集合
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <title>My JSP '2.jsp' starting page</title>
  <meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
  </head>
  
  <body>
  	<s:set var="map" value="#{'1':'aa','2':'bb'}" scope="session"><!-- 默认scope在context中  -->
  	</s:set>

  	<s:iterator value="#sessionScope.map" var="me">
  		<s:property value="#me,key"/>
  	</s:iterator>
  	<!-- 
  			<c:forEach items="${pageScope.map}" var="var">
		${var.key} = ${var.value}<br/>
	</c:forEach>
  	 -->
    ${sessionScope.map}<!-- struts2中最好还是用他自己的标签  无法引用-->
  	  
		
  </body>
</html>

如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。使用如下代码直接生成一个List对象:
<s:set name=“list” value=“{‘a’,’b’,’c’}”/>
<s:iterator value=“#list”>
<s:property/><br/>
</s:iterator>

Set标签用于将某个值放入指定范围。
scope:指定变量被放置的范围,该属性可以接受application、session、request、page或action。如果没有设置该属性,则默认放置在OGNL Context中。
value:赋给变量的值。如果没有设置该属性,则将ValueStack栈顶的值赋给变量。

生成一个Map对象:
<s:set name=“foobar” value=“#{‘foo1’:’bar1’,’foo2’:’bar2’}”/>
<s:iterator value=“#foobar”>
<s:property value=“key”/>=<s:property value=“value”/><br/>
</s:iterator>

二、if判断
对于集合类型,OGNL表达式可以使用in和not in两个元素符号。其中,in表达式用来判断某个元素是否在指定的集合对象中;not in判断某个元素是否不在指定的集合对象中,如下所示:
in表达式:
<s:if test=“’foo’ in {‘foo’,’bar’}”
在
</s:if>
<s:else>
不在
</s:else>
not in 表达式:
<s:if test=“’foo’ in {‘foo’,’bar’}”
不在
</s:if>
<s:else>
在
</s:else>



 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值