Struts2(三)

什么是OGNL?

OGNL(Object-Graph Navigation Language),是一种功能强大的开源表达式语言,可以获取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。

  • EL:从域对象中获取数据,从EL的11个对象中获取。
  • OGNL:调用对象的方法,获取struts2值栈的数据。OGNL其实是第三方的表达式语言。

OGNL的作用?

  • 支持对象方法调用。例如:objName.methodName();
  • 支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名|值名]。例如:@java.lang.String@format('foo %s', 'bar');
  • 支持赋值操作和表达式串联。例如price=100, discount=0.8, calculatePrice(price*discount),这个表达式会返回80;
  • 访问OGNL上下文(OGNL context)和ActionContext;
  • 操作集合对象。

OGNL的要素

  • 表达式:表明此次OGNL操作要“做什么”
  • 根对象:OGNL的操作对象,即root规定“对谁操作”
  • Context对象:root对象所在的环境就是OGNL的上下文环境,规定OGNL的操作“在哪里进行”,上下文环境Context是一个Map类型的对象,在表达式中访问Context中的对象,需要使用“#”号加上对象的名称,即“#对象名称”的形式。

OGNL的Struts环境入门

访问对象的方法

<h3>调用对象的方法</h3>
<s:property value="'helloWord'.length()"/>

访问对象的静态方法

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

什么是值栈?

ValueStack是struts的一个接口,ognlValueStack是ValueStack的实现类,客户端发起一个请求,struts2架构会创建一个Action实例同时创建一个ognlValueStack值栈实例,ognlValueStack贯穿整个Action的生命周期,struts2中使用OGNL将请求Action的参数封装为对象存储到值栈中,并通过OGNL表达式读取值栈中的对象属性值。

ValueStack其实类似于一个数据中转站,struts2框架当中的数据就保存到了ValueStack中。

值栈的内部结构?

结果显示:

 

  • ValueStack中有两个主要的区域:
    • root区域:为CompoundRoot,存储了action实例,它作为ognlContext的Root对象。其实就是一个ArrayList。里面一般放置对象。获取root的数据不需要加#
    • context区域:其实就是一个Map。里面放置的是web开发常用的对象数据的引用。获取context数据需要加#
      • request:
      • session:
      • application:
      • parameters:
      • attr:

值栈与ActionContext的关系

  • ServletContext:Servlet的上下文
  • ActionContext:Action的上下文。
    • 当请求过来的时候,执行过滤器中的doFilter方法,在这个方法中创建ActionContext,在创建ActionContext过程中,创建ValueStack对象,将ValueStack对象传递给ActionContext对象。所以可以通过ActionContext获取值栈对象。
    • ActionContext对象之所以能够访问Servlet的API(访问的是域对象),因为其内部有值栈的引用。

 

获得值栈

  • 通过ActionContext对象获取值栈
//方法一:通过ActionContext获得
ValueStack valueStack1 = ActionContext.getContext().getValueStack();

  •  在Struts2的内部,将值栈存入request中一份
//方法二:通过request获得
ValueStack valueStack2 = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

操作值栈----向值栈中存入数据

  • 一种:在Action中提供属性的get方法的方式
    • 默认情况下,将·Action对象压入到值栈中,Action的属性?(也会在值栈中)
public class ValueStackDemo3 extends ActionSupport{

	private User user;
	
	public User getUser() {
		return user;
	}

	@Override
	public String execute() throws Exception {
		user = new User("李斌","123");
		return SUCCESS;
	}
}
  • 二种:使用ValueStack中本省的方法的方式。
public class ValueStackDemo4 extends ActionSupport{

	@Override
	public String execute() throws Exception {
		
		//获得值栈
		ValueStack valueStack = ActionContext.getContext().getValueStack();
		//使用push(Object obj);    set(String key,Object obj);
		User user = new User("李白","123");
		valueStack.push(user);
		
		valueStack.set("name", "小龙");//创建一个Map集合,将Map压入到栈中
		
		return SUCCESS ;
	}	
}

获取值栈数据

  • 获取值栈中的数据就是在页面中使用OGNL表达式即可。
    • 获取root的数据:不需要加#
<!-- 获取一个对象的数据 -->
<s:property value="username"/>
<s:property value="password"/><br/>
<!-- 获取集合中的数据 -->
<s:property value="list[0].username"/>
<s:property value="list[0].password"/><br/>
<s:property value="list[1].username"/>
<s:property value="list[1].password"/><br/>
<s:property value="list[2].username"/>
<s:property value="list[2].password"/><br/>
  • 获取context数据
<!-- 获取context中的数据 -->
<s:property value="#request.name"/><br/>
<s:property value="#session.name"/><br/>
<s:property value="#application.name"/><br/>
<s:property value="#attr.name"/><br/>
<s:property value="#parameters.id"/><br/>

EL为何访问值栈数据?

因为Struts2框架底层对request.getAttribute(String key)方法做了增强:即先从request中获取数据,如果没有获取到,再从值栈中获取。

OGNL中特殊字符

1、#号

获取context中的数据

<h3>获取context中的数据</h3>
<%
	request.setAttribute("name", "李冰");
%>
<s:property value="#request.name"/>

使用#构建map集合

<s:iterator var="entry" value="#{'a':'1','b':'2','c':'3'}">
<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="sex3" label="性别"></s:radio>

2、%号

强制解析OGNL

<h1>OGNL中%的用法</h1>
<%
	request.setAttribute("name","王东");
%>
姓名:<s:textfield name="name" value="%{#request.na

3、$号

在配置文件中使用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="Content-Type">文件类型</param>
          • <param name="Content-Disposition">attachment;filename=${文件名}</param>
        • </result>
      • </action>

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值