Struts2:OGNL
2015-11-30 11:40
471 查看
OGNL是ObjectGraphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts 2框架使用OGNL作为默认的表达式语言。
相对EL表达式,它提供了平时我们需要的一些功能,如:
l支持对象方法调用,如xxx.sayHello();
l支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名|
值名],例如:@java.lang.String@format('foo%s',
'bar')或@cn.itcast.Constant@APP_NAME;
l操作集合对象。
Ognl有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图
当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。
访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session
另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。
在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象
|--request
|--application
|context ------|--OgnlValueStackroot变量[action,OgnlUtil,
... ]
|--session
|--attr
|--parameters
在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。
注意: Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:propertyvalue="name"/>
由于ValueStack(值栈)是Struts2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:
${foo} //获得值栈中某个对象的foo属性
我们都知道EL表达式只能访问三大域中的对象,但是Struts2中为什么可以访问ValueStack中的属性呢?
原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:
public class StrutsRequestWrapper extendsHttpServletRequestWrapper {
public StrutsRequestWrapper(HttpServletRequestreq) {
super(req);
}
publicObject getAttribute(String s){
......
ActionContextctx =ActionContext.getContext();
Object attribute =
super.getAttribute(s);//先从request范围获取属性值
if (ctx != null) {
if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
......
ValueStack stack =ctx.getValueStack();
attribute =
stack.findValue(s);
......
}
}
return attribute;
}
}
如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。
lapplication对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。
lsession对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
lrequest对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。
lparameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
lattr对象:用于按page->request->session->application顺序访问其属性。
OGNL生成集合
如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。
使用如下代码直接生成一个List对象:
<s:set name="list" value="{'zhangming','xiaoi','liming'}" />
<s:iteratorvalue="#list" id="n">
<s:propertyvalue="n"/><br>
</s:iterator>
生成一个Map对象:
<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}"/>
<s:iterator value="#foobar" >
<s:propertyvalue="key"/>=<s:property value="value"/><br>
</s:iterator>
Set标签用于将某个值放入指定范围。
scope:指定变量被放置的范围,该属性可以接受application、session、request、page或action。如果没有设置该属性,则默认放置在OGNL
Context中。
value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。
OGNL投影
除了in和notin之外,OGNL还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符。
?:获得所有符合逻辑的元素。
^:获得符合逻辑的第一个元素。
$:获得符合逻辑的最后一个元素。
例如代码:
<s:iterator value="books.{?#this.price > 35}">
<s:property value="title" /> - $<s:propertyvalue="price" /><br>
</s:iterator>
在上面代码中,直接在集合后紧跟.{}运算符表明用于取出该集合的子集,{}内的表达式用于获取符合条件的元素,this指的是为了从大集合books筛选数据到小集合,需要对大集合books进行迭代,this代表当前迭代的元素。本例的表达式用于获取集合中价格大于35的书集合。
public class BookAction extendsActionSupport {
privateList<Book> books;
....
@Override
public String execute() {
books= new
LinkedList<Book>();
books.add(new Book("A735619678","spring", 67));
books.add(new Book("B435555322","ejb3.0",15));
}
}
例子(来源于北京圣思园Hibernate开发应用详解视频教程)
相对EL表达式,它提供了平时我们需要的一些功能,如:
l支持对象方法调用,如xxx.sayHello();
l支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名|
值名],例如:@java.lang.String@format('foo%s',
'bar')或@cn.itcast.Constant@APP_NAME;
l操作集合对象。
Ognl有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图
当Struts2接受一个请求时,会迅速创建ActionContext,ValueStack,action。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。
访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#session
另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。
在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象
|--request
|--application
|context ------|--OgnlValueStackroot变量[action,OgnlUtil,
... ]
|--session
|--attr
|--parameters
在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。
注意: Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:propertyvalue="name"/>
由于ValueStack(值栈)是Struts2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性:
${foo} //获得值栈中某个对象的foo属性
我们都知道EL表达式只能访问三大域中的对象,但是Struts2中为什么可以访问ValueStack中的属性呢?
原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下:
public class StrutsRequestWrapper extendsHttpServletRequestWrapper {
public StrutsRequestWrapper(HttpServletRequestreq) {
super(req);
}
publicObject getAttribute(String s){
......
ActionContextctx =ActionContext.getContext();
Object attribute =
super.getAttribute(s);//先从request范围获取属性值
if (ctx != null) {
if (attribute == null) {//如果从request范围没有找到属性值,即从ValueStack中查找对象的属性值
......
ValueStack stack =ctx.getValueStack();
attribute =
stack.findValue(s);
......
}
}
return attribute;
}
}
如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。
lapplication对象:用于访问ServletContext,例如#application.userName或者#application['userName'],相当于调用ServletContext的getAttribute("username")。
lsession对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。
lrequest对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。
lparameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。
lattr对象:用于按page->request->session->application顺序访问其属性。
OGNL生成集合
如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。
使用如下代码直接生成一个List对象:
<s:set name="list" value="{'zhangming','xiaoi','liming'}" />
<s:iteratorvalue="#list" id="n">
<s:propertyvalue="n"/><br>
</s:iterator>
生成一个Map对象:
<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}"/>
<s:iterator value="#foobar" >
<s:propertyvalue="key"/>=<s:property value="value"/><br>
</s:iterator>
Set标签用于将某个值放入指定范围。
scope:指定变量被放置的范围,该属性可以接受application、session、request、page或action。如果没有设置该属性,则默认放置在OGNL
Context中。
value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。
OGNL投影
除了in和notin之外,OGNL还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符。
?:获得所有符合逻辑的元素。
^:获得符合逻辑的第一个元素。
$:获得符合逻辑的最后一个元素。
例如代码:
<s:iterator value="books.{?#this.price > 35}">
<s:property value="title" /> - $<s:propertyvalue="price" /><br>
</s:iterator>
在上面代码中,直接在集合后紧跟.{}运算符表明用于取出该集合的子集,{}内的表达式用于获取符合条件的元素,this指的是为了从大集合books筛选数据到小集合,需要对大集合books进行迭代,this代表当前迭代的元素。本例的表达式用于获取集合中价格大于35的书集合。
public class BookAction extendsActionSupport {
privateList<Book> books;
....
@Override
public String execute() {
books= new
LinkedList<Book>();
books.add(new Book("A735619678","spring", 67));
books.add(new Book("B435555322","ejb3.0",15));
}
}
例子(来源于北京圣思园Hibernate开发应用详解视频教程)
相关文章推荐
- JAVA基础代码分享--模拟人机猜拳系统
- Spring事务管理的三种方式
- spring解决中文乱码问题
- Java学习日记-2.3 基本数据类型和对象所占内存空间大小
- Java线程同步:synchronized锁住的是代码还是对象
- Spring的注解
- java 算法(1)-有序数组
- Java的输入输出流
- Struts2:国际化
- JAVA 随笔(一)
- Struts2:输入校验
- eclipse工程前面出现红色叹号解决方法
- Java数据类型中String、Integer、int相互间的转换
- Java抽象类与接口的区别
- Spring学习笔记(十一):关于微信开发时,用户名包含表情,保存到数据库出错的解决办法
- java 根据图片地址获取到图片的大小,单位kb或者Mb
- java中equals和equalsignorecase的区别
- java 中的定时器设计
- 【Java基础学习】 接口与多态的形象化举例
- java 创建线程