struts2-OGNL基础

OGNL(Object-Graph Navigation Language)是一种强大的表达式语言,是一个第三方开源项目。

OGNL本身是与struts2 没有任何关系 ,但struts2框架使用了OGNL用于进行表达式的计算工作。struts2通过使用OGNL简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转换等功能。

OGNL特点:

  • 支持对象方法调用
  • 可以操作集合对象
  • 可以直接创建对象
  • 支持类静态方法调用和常量访问,表达式的格式为:
    @[全限定性类名]@[方法名|常量名]
    如:@java.lang.Integer@parseInt(“123”)或@java.lang.Math@PI
    不过静态方法的访问,需要通过在struts2的配置文件struts.xml中设置常量struts.ognl.allowStaticMethodAccess的值为true进行开启。

OGNL以map的形式展现其内部(文档原句:The top level object dealing with OGNL is a Map (usually referred as a context map or context)
这里写图片描述

在action中直接获取context及内部的值很麻烦,所以给了context另一个定义,即ActionContext。可以通过ActionContext简单获取。(servletApi值也是存在这里,所以获取的也是这里面的,所以ActionContext.getContext获取的不是真正的request)

ValueStack vs = ActionContext.getContext().getValueStack();//获取值栈

OGNL中的值栈是核心,对其操作方式有如下:(对值栈操作实质上是对其中的root进行操作)

        //向值栈中加入无名对象,实际是放到它的root属性中
        Student st=   new Student("zhangsan",21);
        vs.push(st);

        //向值栈直接放入有名对象,实际是放到它的root属性中
        Student st1 = new Student("lisi",20);
        Map<String, Student> map  = new HashMap<String,Student>();
        map.put("st1", st1);
        vs.push(map);

        Student st2 = new Student("lisi",21);
        vs.set("st2", st2);

        //将root作为ArrayList放入数据
        Student st3 = new Student("wisi",21);
        vs.getRoot().add(st3);
        System.out.println((Student)vs.getRoot().get(5));

通过如下可在页面显示及查看值栈内容:

<%@ 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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<s:debug></s:debug>

name = <s:property value="name"/><br>
age = <s:property value="age"/><br>
st2.name = <s:property value="st2.name"/><br>
st2age = <s:property value="st2.age"/>

</body>
</html>

这里写图片描述
root的实质是ArrayList,所以里面存的对象都是无名对象,只能通过对象的属性来获取相应值


context中数据加载顺序:
当在Action中仅向context中放入某数据lov后,页面无论是通过#从context读取,还是不用#向root读取,都能读到(后者先去root找相关数据,没有就在context下找)

        String lov = "lov";
        ActionContext.getContext().put("lov", lov);
lov = <s:property value="lov"/><br>
#lov = <s:property value="#lov"/><br>

当通过表单发出请求时,表单值传到context.map下的request中,获取其中的值时
# request.name底层执行的是request.getAttribute();
request.getAttribute();被struts2包装后的查找顺序是:
request域空间->root->context

通过request = <%=request %>可以得出,这里的request不是原始的request了:
这里写图片描述


以下为页面中的一些OGNL操作(list,map遍历,条件判断,查询)

<!-- set标签定义的对象均存放于context中 -->
<!-- list -->
<s:set  var="list" value="{'1','2','3'}"></s:set>   
<s:iterator value="list"> <!-- iterator表情默认会将当前的迭代对象放入值栈栈顶 -->
<s:property/><br>  <!-- property标签默认输出值栈栈顶元素 -->
</s:iterator>
<br>
<!-- map -->
<s:set var="map" value="#{'one':'1','two':'2' }"></s:set>
<s:iterator value="#map">
 <s:property/><br>
</s:iterator>
<s:iterator value="#map" var="entry">
 <s:property value="entry"/><br>
</s:iterator>
<s:iterator value="#map">
 <s:property value="key"/>=<s:property value="value"/><br>
</s:iterator>
<!-- 集合元素判断-->
<s:property value="'1' in #map"/>
<s:property value="'1' not in #map"/>
<!-- 集合投影 -->
<s:bean name="com.test.Student" var="st1" >
   <s:param name="name" value="'lov'"></s:param>
   <s:param name="age" value="12"></s:param>
</s:bean>
<s:bean name="com.test.Student" var="st2">
   <s:param name="name" value="'lov'"></s:param>
   <s:param name="age" value="13"></s:param>
</s:bean>
<s:bean name="com.test.Student" var="st3">
   <s:param name="name" value="'lov'"></s:param>
   <s:param name="age" value="13"></s:param>
</s:bean>
<s:set var="students" value="{#st1,#st2,#st3}"></s:set>
<s:set var="studentsName" value="#students.{name}"></s:set>
<s:iterator value="#students">
 <s:property/><br>
</s:iterator>
<s:iterator value="#studentsName">
 <s:property/><br>
</s:iterator>
<!-- 集合查询 -->
<s:iterator value="#students.{^#this.age>11}">
   <s:property/><br>
 </s:iterator>
 <s:iterator value="#students.{$#this.age>11}">
   <s:property/><br>
 </s:iterator>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值