开发者学堂课程【Java Web开发系列课程 - Struts2框架入门:Ognl】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/537/detail/7308
Ognl
内容介绍:
一、Ognl 表达式
二、什么是 ognl
三、Strust2 中使用 ognl 表达式
一、Ognl 表达式
Ognl 其实是一个表达式。
表达式——el,re,ognl,有共同的特征,用比较简洁的表达式来完成比较复杂的操作的功能。
有这个功能,比如 el 表达式,用 el 表达式处理 get 方面较复杂的操作。
Ognl 全称是 object-graph navigation language,对象图形导航语言,相对于 el 语言,除了保持 el 语言的优点外,他的其他优点如下:
能够访问对象的普通方法
能够访问类的静态属性和静态方法
强大的操作集合类对象的能力
支持赋值操作和表达式串联
访问 ognl 上下文和 action context
我们用的是最后一条,访问 ognl 上下文和 action context,
我们有很多其他方式来访问,而且使用他还需要学习一个新的方式,我们可以完全用el 表达式访问来完成功能,structs2里面也用到了这种功能。
Ognl 是对象图形导航语言比el语言的功能更加强大,导航效率也更高。
User{
Teacher t;
}
Taecher{
Address address;
}
user.t.address
通过以上代码就可以用 ognl 很轻松的获取到了。可以访问各种级,关联对象的时候就非常容易。
但是事实上,学 ognl 表达式并不简单,它其实是一个第三方插件,在文档中放了ognl guide,一共有24页,不长,把所有的东西都描述的很详尽,介绍,历史包括syntax 等。
Ognl 的历史
ognl 最初是为了能够使用对象的属性名来建立 ui 组件和控制器之间的联系,试图与控制器进行联系,后来为了应付更加复杂的数据关系 Drew Davidson 发明了一个被他称为 kvcl 的语言。
Luke 参与进来后,用 ANTLR 来实现了该语言,并给他取了新的名字,他后来又使用JavaCC 重新实现了该语言,目前 ognl 由 drew 来维护。
二、什么是 ognl?
Ognl 是 object-graph navigation language 的缩写,从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置 Java 对象的属性,它旨在提供一个更高抽象度语法来对 java 对象图进行导航。Ognl 在许多地方都有应用,
例如:
作为 GUI 元素到模型对象的绑定语言
数据库表到 swing 的 TableModle 的数据源语言
Web 组件和后台 Model 对象的绑定语言
作为 Jakarta Commons BeanUtils 或者 JSTL 的表达式语言的一个更具表达力的替代语言。
Ognl 语言目前只在 strust 里面可以用,其他方面运用较少。在开发过程中,有时也用 el,以前是不限制。
在 strust 中使用 ognl 是因为 strust 中启用了一套标签,这套标签没有必要学习。
大纲中有很多标签,如 ui,structs2 之类等等,一起看常用数据标签。
其余部分没有必要学习,strust1有一套标签,strust2也有一套标签,我们没有必要学习每种标签,我们只需要 gstl 标准的标签即可,gstl是最基础的标签。在开发过程中用的也很少。
使用 ognl
新建一个 java project lib,命名为08structs2_ognl
作为一个第三方库,新建一个 lib
将 ognl 包拷贝进去
Package cn.sxt.test;
Public class Test{
Public static void main(String[] args){
//原则;数据分为2类——常用的和不常用的,不常用的更多 expression 中放 ognl 表达式,context 中放不常用的,root 中放常用的
//表达式:
常用的数据直接取,不常用的数据加#取
Map<String,Object> map=new HashMap<String,Object>();
map.put(“name”,”张三疯”);
Map.put(“age”,125);
Ognl.getvalue(expression,context,root);
}
}
再新建一个 user 的文件
package cn.sxt.entity
public class User{
private String name;
Private string pwd;
Public string getname(){
return name
}
public void setName(String name){
this.name=name;
}
public String getPwd(){
return pwd;
}
public void setPwd(String pwd){
this.pwd=pwd;
}
}
我们构造的是对象,所以一定要用无参的构造方法。因为我们的数据参数是由structs2设置的,没有在对象里创建,所以不需要启动。
在之前代码中写
User user=new User()
user.setName(“lisi”);
Object obj=Ognl.getvalue(“name”,map,user);
常用的一般是小数据,不常用的一般是大数据
执行一下,发现有异常,原因是依赖于其他包javasist,直接拷贝后,在name前加#,
如下,
User user=new User()
user.setName(“lisi”);
Object obj=Ognl.getvalue(“#name”,map,user);
执行后可得名字张三疯。
三、Strust2中使用 ognl 表达式
是通过 strust2的标签来取值的。
在 structs2中它把 ognl 作为 actioncontext 的大数据,把值栈作为它的小数据,我们又把它称为根对象,意味着,如果数据在值栈中可以直接去取,而如果数据在actioncontext 的 appilysession 中则需加#取。
新建一个 lib,09structs2_ognl
将上面的各种包拷贝进去。
简单操作使用演示:
登录好,转发到 success 中
把 error.jop,index.jop,login.jop,success.jop 都放入新建中正常情况下可以直接使用,现在做一些变化,在jsp中导入 strust2 的标签库
<%@taglib prefix=”s”uri=”/strusts-tags-”%>
导入 structs2的标签库,这样之后过滤器才会起作用。
改变 context 中的背景文件。完成后为了给大家测试一个问题
修改
<url-pattern>action</url-pattern>
为
<url-pattern>*.action</url-pattern>
运行
在网址中输入http://localhost:8080/ognl/success.jsp访问网址,直接访问 success 页面。
测试之后发现没有问题。继续进行。
从 strust 中取值可以直接用<s:property value=”name”>
因为这个 value 是actioncontext session 里面的,可以直接访问。其中的 name 也是可以直接取。
原因是值栈可以直接取,值栈里面放的就是loginaction对象,所以通过ognl表达式可以直接访问 action 的属性。一般情况下,访问不到会直接显示空,而现在的状态如下图:
是25行发生了报错。
Struct dispatchat cannot be found
意思是 struct 的核心过滤器无法找到。通常被认为是,struct 的标签没有经过过滤器。
注意:
要使用 strust2的标签,要通过 strust2的过滤器来启用。
代码中可以自定义标签库,标签库需要 Java 类来支持。当 struct 没有用到是,它的过滤器也同样无法被用到。如果过滤器的配置为*.action 结尾时,不能直接访问 jsp 页面的。需要通过 action 跳转。
我们可以正常进行登录步骤不会报错。
Strusts2推荐不直接访问 jsp 页面,转发之后就无法知道它的地址及路径,所以推荐使用 action 来控制。
用/*访问也不会报错,原因是使用/*过滤器也进去了,只是找不到,不会报错。
由于 strust2里面有两个对象放在 ognl 里面取的,放在值栈中,所以它调用的是 get方法。
将之前的 name 换为 user 也同样可以登录。
Action context 是用 get 去取,get session 会被调用,因为它是 map 位置的数据,不是根对象,所以要用#,在 el 中也一样。
Name 取得是 action 中的属性,表达式不一样。原因是它属于 action 对象,是将action 属性直接暴露进去的,所以结论是使用 ognl 访问 action 的属性时可以直接访问。访问 actioncontext 时,需要加#。