OGNL(Object-Graph Navigation Language)的概念:

OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整个对象的结构图,实现对象属性类型的转换等功能。

1.OGNL表达式的计算是围绕OGNL上下文进行的。

OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。

上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。

2.Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的。

如:<s:propertyvalue="xxx"/>。

3.Struts2将ActionContext设置为OGNL上下文,并将值栈作为OGNL的根对象放置到ActionContext中。

4.值栈(ValueStack) :

 可以在值栈中放入、删除、查询对象。访问值栈中的对象不用“#”。
 Struts2总是把当前Action实例放置在栈顶。所以在OGNL中引用Action中的属性也可以省略“#”。
5.调用ActionContext的put(key,value)放入的数据,需要使用#访问。

OGNL中重要的3个符号:#、%、$:

#、%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分,需要时间的积累才渐渐弄清楚……

1.#符号

#符号的用途一般有三种。

—访问非根对象属性,例如#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀。实际上,#相当于ActionContext. getContext();#session.msg表达式相当     于ActionContext.getContext().getSession(). getAttribute("msg") 。

—用于过滤和投影(projecting)集合,如persons.{?#this.age>25},persons.{?#this.name=='pla1'}.{age}[0]。

—用来构造Map,例如示例中的#{'foo1':'bar1', 'foo2':'bar2'}。

2.%符号

%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值,这个类似js中的eval,很暴力。

3.$符号

$符号主要有两个方面的用途。

—在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。

—在Struts 2框架的配置文件中引用OGNL表达式,例如:

1 <validators>
2     <field name="intb">
3             <field-validator type="int">
4             <param name="min">10</param>
5             <param name="max">100</param>
6             <message>BAction-test校验:数字必须为${min}为${max}之间!</message>
7         </field-validator>
8     </field>
9 </validators>   

深入理解OGNL

action类OgnlAction.java:
 1 package com.tjcyjd.test.action;
 2
 3 import java.util.Date;
 4 import java.util.LinkedList;
 5 import java.util.List;
 6
 7 import javax.servlet.http.HttpServletRequest;
 8
 9 import org.apache.struts2.ServletActionContext;
10 import org.apache.struts2.convention.annotation.Action;
11 import org.apache.struts2.convention.annotation.Namespace;
12 import org.apache.struts2.convention.annotation.ParentPackage;
13 import org.apache.struts2.convention.annotation.Result;
14 import org.apache.struts2.convention.annotation.Results;
15 import org.springframework.stereotype.Controller;
16
17 import com.opensymphony.xwork2.ActionContext;
18 import com.opensymphony.xwork2.ActionSupport;
19
20 @Controller
21 @Namespace("/test")
22 @ParentPackage("struts-default")
23 @Results( { @Result(name = "success", location = "/other_test/showognl.jsp"),
24         @Result(name = "fail", location = "/bbs/admin_login.jsp"),
25         @Result(name = "input", location = "/bbs/admin_login.jsp") })
26 public class OgnlAction extends ActionSupport {
27     private static final long serialVersionUID = -1494290883433357310L;
28     private List<Person> persons;
29
30     @Action("ognlTest")
31     public String ognlTest() throws Exception {
32         // 获得ActionContext实例,以便访问Servlet API
33         ActionContext ctx = ActionContext.getContext();
34         // 存入application
35         ctx.getApplication().put("msg", "application信息");
36         // 保存session
37         ctx.getSession().put("msg", "seesion信息");
38         // 保存request信息
39         HttpServletRequest request = ServletActionContext.getRequest();
40         request.setAttribute("msg", "request信息");
41         // 为persons赋值
42         persons = new LinkedList<Person>();
43         Person person1 = new Person();
44         person1.setName("pla1");
45         person1.setAge(26);
46         person1.setBirthday(new Date());
47         persons.add(person1);
48
49         Person person2 = new Person();
50         person2.setName("pla2");
51         person2.setAge(36);
52         person2.setBirthday(new Date());
53         persons.add(person2);
54
55         Person person3 = new Person();
56         person3.setName("pla3");
57         person3.setAge(16);
58         person3.setBirthday(new Date());
59         persons.add(person3);
60
61         return SUCCESS;
62
63     }
64
65     public List<Person> getPersons() {
66         return persons;
67     }
68
69     public void setPersons(List<Person> persons) {
70         this.persons = persons;
71     }
72 }  

jsp页面showognl.jsp:

  1 <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
  2
  3 <%@ taglib prefix="s" uri="/struts-tags" %>
  4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/ xhtml1/DTD/xhtml1-transitional.dtd">
  5
  6 <html xmlns="http://www.w3.org/1999/xhtml">
  7
  8 <head>
  9
 10     <title>Struts2 OGNL 演示</title>
 11
 12 </head>
 13
 14 <body>
 15
 16     <h3>访问OGNL上下文和Action上下文</h3>
 17
 18     <!-使用OGNL访问属性值-->
 19
 20     <p>parameters: <s:property value="#parameters.msg" /></p>
 21
 22     <p>request.msg: <s:property value="#request.msg" /></p>
 23
 24     <p>session.msg: <s:property value="#session.msg" /></p>
 25
 26     <p>application.msg: <s:property value="#application.msg" /></p>
 27
 28     <p>attr.msg: <s:property value="#attr.msg" /></p>
 29
 30     <hr />
 31
 32     <h3>用于过滤和投影(projecting)集合</h3>
 33
 34     <p>年龄大于20</p>
 35
 36     <ul>
 37
 38     <!-判断年龄-->
 39
 40         <s:iterator value="persons.{?#this.age>20}">
 41
 42             <li><s:property value="name" /> - 年龄:<s:property value="age" /></li>
 43
 44         </s:iterator>
 45
 46     </ul>
 47
 48     <p>姓名为pla1的年龄: <s:property value="persons.{?#this.name=='pla1'}.{age}[0]"/></p>
 49
 50     <hr />
 51
 52     <h3>构造Map</h3>
 53
 54     <s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
 55
 56     <p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>
 57
 58     <hr />
 59
 60     <h4>%符号的用法</h4>
 61
 62     <s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
 63
 64     <p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>
 65
 66     <p>不使用%:<s:url value="#foobar['foo1']" /></p>
 67
 68     <p>使用%:<s:url value="%{#foobar['foo1']}" /></p>
 69
 70     <hr />
 71         <%
 72             request.setAttribute("req", "request scope");
 73             request.getSession().setAttribute("sess", "session scope");
 74             request.getSession().getServletContext().setAttribute("app",
 75                     "aplication scope");
 76         %>
 77         1.通过ognl表达式获取 属性范围中的值
 78         <br>
 79         <s:property value="#request.req" />
 80         <br />
 81         <s:property value="#session.sess" />
 82         <br />
 83         <s:property value="#application.app" />
 84         <br />
 85         <hr>
 86
 87        2.通过<span style="background-color: #fafafa;">ognl表达式创建list 集合 ,并且遍历出集合中的值
 88         <br>
 89         <s:set name="list" value="{'eeeee','ddddd','ccccc','bbbbb','aaaaa'}"></s:set>
 90         <s:iterator value="#list" var="o">
 91             <!-- ${o }<br/> -->
 92             <s:property />
 93             <br />
 94         </s:iterator>
 95         <br />
 96         <hr>
 97
 98        3.通过ognl表达式创建Map 集合 ,并且遍历出集合中的值
 99         <br>
100         <s:set name="map"
101             value="#{'1':'eeeee','2':'ddddd','3':'ccccc','4':'bbbbb','5':'aaaaa'}"></s:set>
102         <s:iterator value="#map" var="o">
103             <!--      ${o.key }->${o.value }<br/>   -->
104             <!-- <s:property value="#o.key"/>-><s:property value="#o.value"/><br/>   -->
105             <s:property value="key" />-><s:property value="value" />
106             <br />
107         </s:iterator>
108         <br />
109         <hr>
110       4.通过ognl表达式 进行逻辑判断
111         <br>
112         <s:if test="'aa' in {'aaa','bbb'}">
113             aa 在 集合{'aaa','bbb'}中;
114         </s:if>
115         <s:else>
116             aa 不在 集合{'aaa','bbb'}中;
117         </s:else>
118         <br />
119         <s:if test="#request.req not in #list">
120                 不 在 集合list中;
121         </s:if>
122         <s:else>
123              在 集合list中;
124         </s:else>
125         <br />
126         <hr>
127
128        5.通过ognl表达式 的投影功能进行数据筛选
129         <br>
130         <s:set name="list1" value="{1,2,3,4,5}"></s:set>
131         <s:iterator value="#list1.{?#this>2}" var="o">
132             <!-- #list.{?#this>2}:在list1集合迭代的时候,从中筛选出当前迭代对象>2的集合进行显示 -->
133             ${o }<br />
134         </s:iterator>
135         <br />
136         <hr>
137        6.通过ognl表达式 访问某个类的静态方法和值
138         <br>
139         <s:property value="@java.lang.Math@floor(32.56)" />
140
141         <s:property value="@com.rao.struts2.action.OGNL1Action@aa" />
142         <br />
143         <br />
144         <hr>
145       7.ognl表达式 迭代标签 详细
146         <br>
147         <s:set name="list2"
148             value="{'aa','bb','cc','dd','ee','ff','gg','hh','ii','jj'}"></s:set>
149         <table border="1">
150             <tr>
151                 <td>索引 </td>
152                 <td>值</td>
153                 <td>奇?</td>
154                 <td> 偶?</td>
155                 <td>首?</td>
156                 <td> 尾?</td>
157                 <td>当前迭代数量</td>
158             </tr>
159             <s:iterator value="#list2" var="o" status="s">
160                 <tr bgcolor="<s:if test="#s.even">pink</s:if>">
161                     <td>
162                         <s:property value="#s.getIndex()" />
163                     </td>
164                     <td>
165                         <s:property />
166                     </td>
167                     <td>
168                         <s:if test="#s.odd">Y</s:if>
169                         <s:else>N</s:else>
170                     </td>
171                     <td>
172                         <s:if test="#s.even">Y</s:if>
173                         <s:else>N</s:else>
174                     </td>
175                     <td>
176                         <s:if test="#s.first">Y</s:if>
177                         <s:else>N</s:else>
178                     </td>
179                     <td>
180                         <s:if test="#s.isLast()">Y</s:if>
181                         <s:else>N</s:else>
182                     </td>
183                     <td>
184                     <s:property value="#s.getCount()"/>
185                 </td>
186                 </tr>
187             </s:iterator>
188         </table>
189         <br>
190         <hr>
191
192
193        8.ognl表达式:  if/else if/else 详细<br>
194         <% request.setAttribute("aa",0); %>
195         <s:if test="#request.aa>=0 && #request.aa<=4">
196                 在0-4之间;
197         </s:if>
198         <s:elseif test="#request.aa>=4 && #request.aa<=8">
199                 在4-8之间;
200         </s:elseif>
201         <s:else>
202              大于8;
203         </s:else>
204         <br>
205         <hr>
206     9.ognl表达式: url 详细<br>
207         <% request.setAttribute("aa","sss"); %>
208         <s:url action="testAction" namespace="/aa/bb">
209             <s:param name="aa" value="#request.aa"></s:param>
210             <s:param name="id">100</s:param>
211         </s:url>
212         <br/>
213         <s:set name="myurl" value="'http://www.baidu.com'"></s:set>
214         value以字符处理:   <s:url value="#myurl"></s:url><br>
215         value明确指定以ognl表达式处理:    <s:url value="%{#myurl}"></s:url>
216         <br>
217         <hr>
218     10.ognl表达式: checkboxlist 详细<br>
219         1> .list 生成;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
220         name:checkboxlist的名字<br>
221         list:checkboxlist要显示的列表<br>
222         value:checkboxlist默认被选中的选项,checked=checked<br>
223         <s:checkboxlist name="checkbox1" list="{'上网','看书','爬山','游泳','唱歌'}" value="{'上网','看书'}" ></s:checkboxlist>
224         <br>
225          以上生成代码:<br>
226         <xmp>
227             <input type="checkbox" name="checkbox1" value="上网" id="checkbox1-1" checked="checked"/>
228             <label for="checkbox1-1" class="checkboxLabel">上网</label>
229             <input type="checkbox" name="checkbox1" value="看书" id="checkbox1-2" checked="checked"/>
230             <label for="checkbox1-2" class="checkboxLabel">看书</label>
231             <input type="checkbox" name="checkbox1" value="爬山" id="checkbox1-3"/>
232             <label for="checkbox1-3" class="checkboxLabel">爬山</label>
233             <input type="checkbox" name="checkbox1" value="游泳" id="checkbox1-4"/>
234             <label for="checkbox1-4" class="checkboxLabel">游泳</label>
235             <input type="checkbox" name="checkbox1" value="唱歌" id="checkbox1-5"/>
236             <label for="checkbox1-5" class="checkboxLabel">唱歌</label>"
237         </xmp>
238         2> .Map 生成;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
239         name:checkboxlist的名字<br>
240         list:checkboxlist要显示的列表<br>
241         listKey:checkbox 的value的值<br>
242         listValue:checkbox 的lablel(显示的值)<br>
243         value:checkboxlist默认被选中的选项,checked=checked<br>
244         <s:checkboxlist name="checkbox2" list="#{1:'上网',2:'看书',3:'爬山',4:'游泳',5:'唱歌'}" listKey="key" listValue="value" value="{1,2,5}" ></s:checkboxlist>
245         <br>
246                        以上生成代码:<br>
247         <xmp>
248             <input type="checkbox" name="checkbox2" value="1" id="checkbox2-1" checked="checked"/>
249             <label for="checkbox2-1" class="checkboxLabel">上网</label>
250             <input type="checkbox" name="checkbox2" value="2" id="checkbox2-2" checked="checked"/>
251             <label for="checkbox2-2" class="checkboxLabel">看书</label>
252             <input type="checkbox" name="checkbox2" value="3" id="checkbox2-3"/>
253             <label for="checkbox2-3" class="checkboxLabel">爬山</label>
254             <input type="checkbox" name="checkbox2" value="4" id="checkbox2-4"/>
255             <label for="checkbox2-4" class="checkboxLabel">游泳</label>
256             <input type="checkbox" name="checkbox2" value="5" id="checkbox2-5" checked="checked"/>
257             <label for="checkbox2-5" class="checkboxLabel">唱歌</label>
258         </xmp>
259         <hr>
260 </body>
261 </html>    

ONGL总结

访问属性

名字属性获取:<s:property value="user.username"/><br>

地址属性获取:<s:property value="user.address.addr"/><br>

访问方法

调用值栈中对象的普通方法:<s:property value="user.get()"/><br>

访问静态属性和方法

调用Action中的静态方法:<s:property value="@struts.action.LoginAction@get()"/>

调用JDK中的类的静态方法:<s:property value="@Java.lang.Math@floor(44.56)"/><br>

调用JDK中的类的静态方法(同上):<s:property value="@@floor(44.56)"/><br>

调用JDK中的类的静态方法:<s:property value="@java.util.Calendar@getInstance()"/><br>

调用普通类中的静态属性:<s:property value="@struts.vo.Address@TIPS"/><br>

访问构造方法

调用普通类的构造方法:<s:property value="new struts.vo.Student('李晓红' , '美女' , 3 , 25).username"/>

1.5. 访问数组

获取List:<s:property value="testList"/><br>

获取List中的某一个元素(可以使用类似于数组中的下标获取List中的内容):

<s:property value="testList[0]"/><br>

获取Set:<s:property value="testSet"/><br>

获取Set中的某一个元素(Set由于没有顺序,所以不能使用下标获取数据):

<s:property value="testSet[0]"/><br> ×

获取Map:<s:property value="testMap"/><br>

获取Map中所有的键:<s:property value="testMap.keys"/><br>

获取Map中所有的值:<s:property value="testMap.values"/><br>

获取Map中的某一个元素(可以使用类似于数组中的下标获取List中的内容):

<s:property value="testMap['m1']"/><br>

获取List的大小:<s:property value="testSet.size"/><br>

访问集合 – 投影、选择(? ^ $)

利用选择获取List中成绩及格的对象:<s:property value="stus.{?#this.grade>=60}"/><br>

利用选择获取List中成绩及格的对象的username:

<s:property value="stus.{?#this.grade>=60}.{username}"/><br>

利用选择获取List中成绩及格的第一个对象的username:

<s:property value="stus.{?#this.grade>=60}.{username}[0]"/><br>

利用选择获取List中成绩及格的第一个对象的username:

<s:property value="stus.{^#this.grade>=60}.{username}"/><br>

利用选择获取List中成绩及格的最后一个对象的username:

<s:property value="stus.{$#this.grade>=60}.{username}"/><br>

利用选择获取List中成绩及格的第一个对象然后求大小:

<s:property value="stus.{^#this.grade>=600}.{username}.size"/><br>

集合的伪属性

OGNL能够引用集合的一些特殊的属性,这些属性并不是JavaBeans模式,例如size(),length()等等. 当表达式引用这些属性时,OGNL会调用相应的方法,这就是伪属性.

集合

伪属性

Collection(inherited by Map, List & Set)

size ,isEmpty

List

iterator

Map

keys , values

Set

iterator

Iterator

next , hasNext

Enumeration

next , hasNext , nextElement , hasMoreElements

Lambda   :[…]

格式::[…]

使用Lambda表达式计算阶乘:

<s:property value="#f = :[#this==1?1:#this*#f(#this-1)] , #f(4)"/><br>

OGNL中#的使用

#可以取出堆栈上下文中的存放的对象.

名称

作用

例子

parameters

包含当前HTTP请求参数的Map

#parameters.id[0]作用相当于

request.getParameter("id")

request

包含当前HttpServletRequest的属性(attribute)的Map

#request.userName相当于

request.getAttribute("userName")

session

包含当前HttpSession的属性(attribute)的Map

#session.userName相当于

session.getAttribute("userName")

application

包含当前应用的ServletContext的属性(attribute)的Map

#application.userName相当于

application.getAttribute("userName")

attr

用于按request > session > application顺序访问其属性(attribute)

Struts2 OGNL相关推荐

  1. Struts2 OGNL表达式注入漏洞解决

    Struts2 OGNL表达式注入漏洞解决 线上项目使用Struts2 版本2.3,需要升级版本,记录解决步骤,不确保其它项目都可以 pom.xml <struts.version>2.5 ...

  2. struts2 ognl 判断数据类型_新华三攻防系列之防护篇从防护角度看Struts2历史漏洞...

    前言 Struts2漏洞是一个经典的漏洞系列,根源在于Struts2引入了OGNL表达式使得框架具有灵活的动态性.随着整体框架的补丁完善,现在想挖掘新的Struts2漏洞会比以前困难很多,从实际了解的 ...

  3. Struts2 ognl表达式

    一.实验目的 1. 掌握OGNL表达式的语法结构 2. 掌握OGNL表达式获取Action中的相关值的方法. 3. 理解投影的含义. 二.实验内容 创建业务控制类OgnlAction,测试基本属性.基 ...

  4. struts2 OGNL表达式

    一.OGNL OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对 ...

  5. Struts2 ognl判断集合对象是否为空的方法

    让我啰嗦两句 项目在使用struts2的时候,需要在前端对后端传过来的对象进行一个判空处理.所以就简单的使用ognl test一下,但是bug就这么出来了. 简单看一下: No result defi ...

  6. Struts2 OGNL标签

    1.设置jsp页面 <%@ page language="java" pageEncoding="utf-8" contentType="tex ...

  7. Struts2 ognl中的#、%和$符号用法说明

    2019独角兽企业重金招聘Python工程师标准>>> 1.#符号的用途一般有三种.    1)访问非根对象属性,例如示例中的#session.msg表达式,由于Struts 2中值 ...

  8. Struts2中的OGNL详解

    2019独角兽企业重金招聘Python工程师标准>>> 首先了解下OGNL的概念: OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航 ...

  9. java ognl表达式 与struts2标签_Struts2 OGNL表达式实例详解

    Object Graph Navigation Language:对象图导航语言,就是用点来访问成员变量 例1: struts.xml: /ognl.jsp OgnlAction1.java: pac ...

最新文章

  1. 计算机视觉:Bag of words算法实现过程中出现错误及解决方案
  2. 【Prometheus】 Prometheus 入门到实战搭建监控系统
  3. 【进程通信】Signal信号
  4. python守护进程进程池_Python3标准库:multiprocessing像线程一样管理进程
  5. ATLAS数学库编译
  6. Java JTable3
  7. python query方法_Pandas dataframe.query方法语法
  8. 在Hadoop集群实施成功后再次格式化名称节点,datanode无法加入集群的处理办法
  9. idea @value提示_IDEA 中springboot 项目使用 注解Autowired 出现红线
  10. ListView自适应实现表格
  11. 洛谷 P1843 奶牛晒衣服 1
  12. 【Protel】Protel99SE(附汉化包+SP6+增强工具+视频教程)
  13. AddressBook 相关操作小计
  14. 阿里云和本地网络安装clone GitHub代码很慢的解决
  15. 家庭光纤宽带延长光纤
  16. 【Java二十周年】我的JAVA小时代
  17. 《一步一步看源码:Nacos》框架源码系列之一(其1,配置服务源码)
  18. python 前端框架比较_浅谈五大Python Web框架
  19. 1000瓶毒水的问题
  20. 【分析数据集各类GT数量分布】

热门文章

  1. NFS4文件锁机制探秘
  2. Sublime Text怎么快速建立一个html5页面模板
  3. A5-1和DES两个加密算法的学习
  4. 如何在Lua与C/C++之间实现table数据的交换
  5. MindFusion Pack for ASP.NET发布v2013.R2
  6. 33条C#、.Net经典面试题目及答案[zt]
  7. 斑马无线打印服务器,如何设置斑马打印机无线WiFi
  8. 18.phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613)
  9. 极大似然估计与贝叶斯定理
  10. linux lsof/netstat查看进程和端口号相关命令: