OGNL(对象图导航语言)学习
一、关于OGNL(Object-Graph Navigation Language),一种可以方便地操作对象属性的开源表达式语言。
特点: 1)支持对象方法调用,形式如:objName.methodName();
2)支持类静态的方法调用和值访问,表达式的格式为@[类全名(包括包路)]@[方法名 | 值名]
3)支持赋值操作和表达式串联,
4)访问OGNL上下文(OGNL context)和ActionContext;
5)操作集合对象。
1.新建项目:并且有一个主包com.bjsxt.struts2.ognl。

2.最重要是的配置struts.xml文件,关乎action的具体动作和行为,此处只是设置了struts的具体权限,可以执行实例方法等。
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<include file="com/bjsxt/struts2/ognl/ognl.xml"/>
</struts>
3.配置ognl.xml文件。主要指引struts去执行对应的action。
<struts>
<package name="ognl" extends="struts-default">
<action name="ognl" class="com.bjsxt.struts2.ognl.OgnlAction">
<result>/ognl.jsp</result>
</action>
<action name="test" class="com.bjsxt.struts2.ognl.TestAction">
<result type="chain">ognl</result>
</action>
</package>
</struts>
4.写OgnlAction的方法:为了实践ognl表达式,就设置了包括有User、Dag、Cat、Map、List、Set等类,并且具体某个类具有的方法也不一。
package com.bjsxt.struts2.ognl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.opensymphony.xwork2.ActionSupport;
public class OgnlAction extends ActionSupport {
private Cat cat;
private Map<String, Dog> dogMap = new HashMap<String, Dog>();
private Set<Dog> dogs = new HashSet<Dog>();
private String password;
private User user;
private String username;
private List<User> users = new ArrayList<User>();
public OgnlAction() {
users.add(new User(1));
users.add(new User(2));
users.add(new User(3));
dogs.add(new Dog("dog1"));
dogs.add(new Dog("dog2"));
dogs.add(new Dog("dog3"));
dogMap.put("dog100", new Dog("dog100"));
dogMap.put("dog101", new Dog("dog101"));
dogMap.put("dog102", new Dog("dog102"));
}
public String execute() {
return SUCCESS;
}
public Cat getCat() {
return cat;
}
public Map<String, Dog> getDogMap() {
return dogMap;
}
public Set<Dog> getDogs() {
return dogs;
}
public String getPassword() {
return password;
}
public User getUser() {
return user;
}
public String getUsername() {
return username;
}
public List<User> getUsers() {
return users;
}
public String m() {
return "hello";
}
public void setCat(Cat cat) {
this.cat = cat;
}
public void setDogMap(Map<String, Dog> dogMap) {
this.dogMap = dogMap;
}
public void setDogs(Set<Dog> dogs) {
this.dogs = dogs;
}
public void setPassword(String password) {
this.password = password;
}
public void setUser(User user) {
this.user = user;
}
public void setUsername(String username) {
this.username = username;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
4.1 User类:User只有一个属性Age,并且具有它自身相应的get和set方法,以及值栈输出需要具有的toString方法。
package com.bjsxt.struts2.ognl;
public class User {
private int age = 8;
public User() {
}
public User(int age) {
super();
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "user" + age;
}
}
4.2 Cat类:在这个类中定义了Cat的friend Dog,以及Cat自身具有的一个方法miaomiao(),这样定义也就意味着访问Dog时需要在地址栏输入cat.friend.name=?才能访问到Cat 的friend: Dog。
package com.bjsxt.struts2.ognl;
public class Cat {
private Dog friend;
public Dog getFriend() {
return friend;
}
public String miaomiao() {
return "miaomiao";
}
public void setFriend(Dog friend) {
this.friend = friend;
}
}
4.3 Dog类:定义了Dog的一个属性name,相应的需要get,set,toString 方法。
package com.bjsxt.struts2.ognl;
public class Dog {
private String name;
public Dog() {
}
public Dog(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "dog: " + name;
}
}
4.4 S类:主要用于测试static静态方法的调用,如果调用成功则返回一个 "static method";。
package com.bjsxt.struts2.ognl;
public class S {
public static String STR = "STATIC STRING";
public static String s() {
return "static method";
}
}
4.5 TestAction类
package com.bjsxt.struts2.ognl;
import com.opensymphony.xwork2.ActionSupport;
public class TestAction extends ActionSupport {
@Override
public String execute() throws Exception {
return super.execute();
}
}
5.V层: index.jsp,只有一个超链接,点击超链接即可出现各种属性的访问情况。现在从页面手动传过去了一个username:admin和password:123。
<%
String contextPath = request.getContextPath();
%>
<body>
访问属性
<a href="<%=contextPath %>/ognl.action?username=admin&password=123">ognl</a>
</body>
6.ognl.jsp:此页面用于显示各个属性访问情况。
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>OGNL表达式语言学习</title>
</head>
<body>
<ol>
<li>访问值栈中的action的普通属性: username = <s:property value="username" />
</li>
<li>访问值栈中对象的普通属性(get set方法):<s:property value="user.age" /> | <s:property
value="user['age']" /> | <s:property value="user[\"age\"]" /> |
wrong: <s:property value="user[age]" /></li>
<li>访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name" /></li>
<li>访问值栈中对象的普通方法:<s:property value="password.length()" /></li>
<li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()" /></li>
<li>访问值栈中action的普通方法:<s:property value="m()" /></li>
<hr />
<li>访问静态方法:<s:property value="@com.bjsxt.struts2.ognl.S@s()" /></li>
<li>访问静态属性:<s:property value="@com.bjsxt.struts2.ognl.S@STR" /></li>
<li>访问Math类的静态方法:<s:property value="@@max(2,3)" /></li>
<hr />
<li>访问普通类的构造方法:<s:property
value="new com.bjsxt.struts2.ognl.User(8)" /></li>
<hr />
<li>访问List:<s:property value="users" /></li>
<li>访问List中某个元素:<s:property value="users[1]" /></li>
<li>访问List中元素某个属性的集合:<s:property value="users.{age}" /></li>
<li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]" /> |
<s:property value="users[0].age" /></li>
<li>访问Set:<s:property value="dogs" /></li>
<li>访问Set中某个元素:<s:property value="dogs[1]" /></li>
<li>访问Map:<s:property value="dogMap" /></li>
<li>访问Map中某个元素:<s:property value="dogMap.dog101" /> | <s:property
value="dogMap['dog101']" /> | <s:property value="dogMap[\"dog101\"]" /></li>
<li>访问Map中所有的key:<s:property value="dogMap.keys" /></li>
<li>访问Map中所有的value:<s:property value="dogMap.values" /></li>
<li>访问容器的大小:<s:property value="dogMap.size()" /> | <s:property
value="users.size" />
</li>
<hr />
<li>投影(过滤):<s:property value="users.{?#this.age==1}[0]" /></li>
<li>投影:<s:property value="users.{^#this.age>1}.{age}" /></li>
<li>投影:<s:property value="users.{$#this.age>1}.{age}" /></li>
<li>投影:<s:property value="users.{$#this.age>1}.{age} == null" /></li>
<hr />
<li>[]:<s:property value="[0].username" /></li>
</ol>
<s:debug></s:debug>
</body>
</html>
注:正则表达式;?#:表示过滤条件;^#:表示开头;$#:表示结束。
7.运行、调试。
7.1 我们先把部分属性打上注释:先访问值栈对象中属性即方法。可以发现只访问到部分属性。

用Debug方式可以发现只有手动输入的username和password有值,而user是空的 ,说明其对应的age默认值是8都取不到。

所以我们需要在地址栏手动输入对应的age就可以实现取值:

从结果可以看出Cat的friend :Dog没有名字给它,所以没有结果:

我们只要在地址栏输入cat.friend.name=Cookie即(曲奇)即可看到运行结果显示了Dog 的名字是Cookie

还有就是访问值栈对象中的普通方法即Cat自己独有的"miaomiao()"也是空值,按照之前的Cat方法来看,应该输出“miaomiao”才对。

是的,解决办法还是如出一辙,即手动输入Cat具有的方法miaomiao(),只是在地址栏输入要跟ognl.jsp中的一致:cat.mioamiao。

7.2 运行测试静态方法,可以发现静态方法没有访问到。

原因是struts.xml中没有设置权限,加上这句话:<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>即可。

注:访问静态方法:<s:property value="@cn.cqvie.ognldemo.S@s()"/>@类名@方法名(或者属性名)。
toStrng()方法:用于打印出某些字符串(对象)而且形式较为规范。
若是写成:@@max(2,3)也不奇怪,只是这样就只能访问该类的属性,一般不常用。
7.3测试List、Map、Set方法:
Set:无序、不重复, 所以无法访问到具体的某个值栈,也没有意义。可以按照默认排序,也可以通
过实现java.util.Comparator<Type>接口来自定义排序方式。
Map: 每一个元素包含一个键对象和值对象,它们成对出现。键对象不能重复,值对象可以重复。
List:有序可以重复,可以访问到值栈中的某个特定的属性。允许按照对象在集合中的索引位置检索对
象,如通过list.get(i)方式来获得List集合中的元素。

7.4 ognl的过滤、投影方法

正如之前所分析的一样,Set是无序的,所以无法访问到该集合中具体的键值。所以是空的。
8.总结、教训
8.1 各种表达式需要熟练运用,才能掌握其中的奥妙,并且联合起来运用,而我用的很吃力,原因是没有深究过其中的门道;
但是通过今天我似乎熟悉了很多,学会运用这个表达式可以省好多事。
8.2 ognl表达式算是一个新知识了,我还做不到完全接受,但是现在不代表以后,我相信时间可以沉淀自己。
8.3 在学习这个标签的过程中,感觉还是Java基础不牢固,以至于很多常用的方法都理解不来,还有很多东西需要加强学习。
8.4 需要明白的一点是当自己没有创建构造方法时,系统会自动为你创建一个无参的构造方法并调用;当你自己创建了一个
有参的构造方法时,系统将不会再创建无参的构造方法。
8.5 ognl表达式:必须要使用对象.属性才能传值即构造出一个对象。必须提供一个空的构造方法,否则系统不会自动调用
那个无参的构造方法,即无法初始化,不会自动new 一个对象,从而不会调用到对象的属性和值。
OGNL(对象图导航语言)学习的更多相关文章
- Ognl对象图导航语言 源码
// -------------------------------------------------------------------------- // Copyright (c) 1998- ...
- Struts_OGNL(Object Graph Navigation Language) 对象图导航语言
1.访问值栈中的action的普通属性: 请求: <a href="ognl.action?username=u&password=p">访问属性</a& ...
- java struts2入门学习--防止表单重复提交.OGNL语言学习
一.知识点回顾 防止表单重复提交核心思想: 客户端和服务器端和写一个token,比较两个token的值相同,则非重复提交;不同,则是重复提交. 1.getSession三种方式比较: request. ...
- C语言学习 第八次作业总结
本次作业其实没有新的内容,主要就是复习上一次的一维数组的相关内容.冯老师布置了5道题目,其中涉及到一些比较简单的排序或者是查找的方法.因为数据很少,所以直接使用for循环遍历就可以了. 关于本次作业, ...
- C语言学习 第七次作业总结
C语言学习 第七次作业总结 数组可以分为数组和多下标数组(在传统的国内C语言书本中,将其称为二/多维数组). 数组名称 在之前的课程中,大家应该都有印象,对于int a这样的定义,会为变量 a 声明一 ...
- 技能收获与C语言学习
你有什么技能比大多人(超过90%以上)更好? 我会的东西很多,喜欢的东西太多,但是很遗憾广而不专,会而不精.学了很多东西我都是为了娱乐,因为以前我们那里过于强调学习,很多爱好也都被扼杀在摇篮里.我觉得 ...
- 一份关于Swift语言学习资源的整理文件
一份关于Swift语言学习资源的整理文件 周银辉 在这里下载 https://github.com/ipader/SwiftGuide
- go语言学习笔记
Go语言学习基本类型Bool 取值范围:true,false (不可以用数字代替)Int/uint 根据平台可能为32或64位int8/uint8 长度:1字节 取值范围-128~127/0~255b ...
- 20155206赵飞技能获取经验,C语言学习感想与对JAVA的学习目标
自己较强的技能获取经验. 1:实话实说我自己是没有哪个技能可以超过90%的人的,只有自认为做的还可以的一些事情,例如打篮球,office软件的应用,一百米跑.至于其他方面就是很平庸了. 2:经验主要有 ...
随机推荐
- python爬虫-采集英语翻译
http://fanyi.baidu.com/?aldtype=85#en/zh/drughttp://fanyi.baidu.com/?aldtype=85#en/zh/cathttp://fa ...
- tomcat配置好后,启动eclipse中的server,不能出现有猫的页面,提示404
原因:tomcat与eclipse中的server未关联起来 解决办法:双击servers中的server,在Server Locations中选中第二项,保存之后再进行刚才的操作就好了.
- 转 -- Python: 多继承模式下 MRO(Method Resolution Order) 的计算方式关乎super
大家可能已经知道了,在 Python 3(Python 2 的新式类)中多继承模式是使用 C3 算法来确定 MRO(Method Resolution Order) 的. 那么具体是怎么计算的呢?本文 ...
- 从面向对象的角度重新认识JS世界
一. 背景 距离上一篇JS文章已经20天,经重新总结发现,上一篇概况的有点浅显,适合初学js的入门了解,但对于已经学习js一段时间的人,或者是想系统的了解JS体系,接下来的文章可能会更有帮助. 该系 ...
- ueditor 百度编辑器,自定义右键菜单
如图:有2种自定义方法,一种是改源码,一种是初始化 初始化,如下代码: var ue = UE.getEditor('XXXid',{ // contextMenu:[ {label:'', cmdN ...
- edge box
先介绍一下matlab与c混合编程 主要步骤: 使用c语言编写函数 利用mexFunction()函数创建C与matlab接口 从Matlab中编译函数 # include <mex.h> ...
- C++中的memset、zeroMemory和={0}操作( 转)
使用C/C++编程时,常使用ZeroMemory.memset或 “={0}”来对结构体对象进行初始化或清零.然而这三种方式都有各自的特点,使用时需谨慎,否则容易出现严重错误,本人今日解决一个导致宕机 ...
- tensorflow神经网络拟合非线性函数与操作指南
本实验通过建立一个含有两个隐含层的BP神经网络,拟合具有二次函数非线性关系的方程,并通过可视化展现学习到的拟合曲线,同时随机给定输入值,输出预测值,最后给出一些关键的提示. 源代码如下: # -*- ...
- luogu P1052 过河
传送门 容易想到设\(f_i\)表示走到坐标\(i\)的最少走过的石子数 但是这题数据范围很大,,, 不过一次可以走的步数范围是1-10,石子个数最多100个,所以中间会有很多多出来的没石子的路,可以 ...
- HDU2255 奔小康赚大钱 【KM算法】
题意: 每个人对不同房有不同出价,就是就是怎样匹配卖房让收入达到最大. 思路: 建立二分图,一边为N家老百姓,还有一边为N间房子.对老百姓和房子之间估价建立一条有带权边.问题就转变为了再二分图中找出一 ...