OGNL表达式和Struts2标签
来源:互联网 发布:php参考手册中文版下载 编辑:程序博客网 时间:2024/06/07 18:20
OGNL的全称是Object Graph Navigation Language(对象图形导航语言),它是一种强大的表达式语言,开发者可以通过简单一致的表达式语法来读取和设置java对象的属性值,调用对象的方法,遍历整个对象的结构。
操作对象!
OGNL有一个上下文(Context)概念,通俗的说就是一个Map结构,它实现了java.util.Map接口,在struts2中上下文(Context)的实现为ActionContext。即Struts2中OGNL Context实现者为ActionContext,它的结构示意图如下:
当Struts2接受一个请求时,会迅速创建ActionContext,然后创建ValueStack,再创建action。接着把action存放到ValueStack中,所以action中的实例变量可以被OGNL表达式直接访问。
OGNL表达式访问各个命名空间的属性:
1.访问上下文(Context)中的对象需要使用#符号标注命名空间,如#application、#Session...
2.另外OGNL会设定一个根对象(root对象),在struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即值栈ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。
3.在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是存放单个值,而是存放一组对象。在OgnlValueStack类里面有一个List类型的root变量,就是使用它来存放一组对象,如图:
4.在root变量中处于第一位的对象叫做栈顶对象。通常我们在OGNL表达式里直接写上熟悉你的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象开始寻找,依次往下访问,知道找到为止。
如:要访问存在栈顶中的一个name属性,我们不需要用到#命名空间的方式,可以直接使用对象属性名称的方式访问,即写个name即可,但是这样写又是无效的,在struts2中,OGNL表达式需要配合struts2标签才可以使用,应该写成这样:<s:property value="name">,这个name就是OGNL表达式。
5.访问值栈ValueStack中的对象,除了直接写属性名称以外,还可以使用EL表达式直接访问,如上面的name,可以这样访问:${name}。
注:EL表达式只限于访问值栈ValueStack中的对象的属性,如果要访问其他域的属性还得使用#命名空间的方式。
Application对象:用于访问ServletContext,例如:#application.userName或者#application['userName'](注【】的形式在一些特殊字符的时候使用,如#applicaiton['u-name']),这样相当于调用了ServletContext的getAttribute("username");
session对象:用来访问HttpSession,例如:#sesion.userName或者#session['userName'],相当于调用session.getAttribute("userName");
request对象:用来访问HttpServletRequest属性,例如:#request.userName或者#request['userName'],相当于调用request.getAttribute("userName");
parameters对象:用来访问Http的请求参数,例如:#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("userName");
attr对象:用于按page->request->session->application顺序访问属性。
在JSP中使用strus2的标签,必须要引入标签声明:
<%@taglib prefix="s" uri="/struts-tags" %>
1.set标签:用于将某个值放入指定的范围。
参数:
注:如果没有设置scope范围,那么默认为OGNL Context(访问时不需要命名空间,使用#即可)。
测试代码:
<body> <s:set name="age" value="22"></s:set> </body>
注:上述代码没有指定范围,即将age放入OGNL Context中,访问时使用#age即可。
2.property标签:用于输出指定的值:
value属性:可选,指定需要输出的属性值,如果没有该属性,则默认输出ValueStack栈顶的值(这个非常重要,有些时候不写value也可以输出,是因为要访问的属性在栈顶)。
测试代码1(访问request范围的属性):
<body><%request.setAttribute("name", "习近平");%> <!-- 访问request范围内的属性,要使用#命名空间的形式 -->名称:<s:property value="#request.name"/> </body>
效果:
测试代码2(访问Session范围的属性):
<body><%session.setAttribute("name", "李克强");%> <!-- 访问session范围内的属性,要使用#命名空间的形式 -->名称:<s:property value="#session.name"/> </body>
效果:
测试代码3(访问值栈中的属性):
/** * 在请求访问action的时候,系统会迅速创建ActionContext->valueStack->action * 并且把action存放在valueStack中,这就是为什么OGNL表达式可以直接以属性名称的方式访问属性。 * 因为action存放在了valueStack中。 * @author Liao * */public class UserAction extends ActionSupport {private static final long serialVersionUID = 1L;private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public String execute(){this.setName("胡锦涛");return this.SUCCESS;}}
在界面访问:
<body><!-- 访问valueStack中的属性,不需要使用#命名空间的形式,直接通过属性名的方式即可访问 -->名称:<s:property value="name"/> <br><!-- 值栈的值也可以直接通过EL表达式来访问 -->通过EL表达式获取的名称:${name} </body>
效果:
3.Iterator迭代标签:用于遍历集合(java.util.Collection)或者枚举值(java.util.iterator)。
参数:
注:value为可选属性,指定被迭代的集合,如果没有设置该属性,则使用ValueStack栈顶的集合。
在演示之前我们先看另外一个知识点:通过OGNL表达式来创建List/Map集合。
测试代码:
<body> <!-- 通过OGNL可以创建List和Map集合value="{'邓小平','胡锦涛','习近平'}"表示一个List集合 --> <s:set name="list" value="{'邓小平','胡锦涛','习近平'}"/> <!-- 上述集合没有指定范围就表示OGNL Context范围内的变量,使用#即可 ,iterator标签中的value表示要迭代的集合--> <s:iterator value="#list"> <!-- 注:Iterator标签在迭代集合时,会把当前迭代的对象放在值栈的栈顶,所以使用property标签输出时可以不用value --> <s:property /><br> </s:iterator> </body>
注:一定要记住,iterator标签在迭代集合时会把当前迭代的对象放在值栈的栈顶,这就是为什么使用property输出值时可以不写value属性的原因。
效果:
使用OGNL创建Map集合:
测试代码【通过OGNL可以创建List和Map集合value="#{'key1':'邓小平','key2':'胡锦涛','key3':'习近平'}"表示一个map集合(注意书写方式)】:
测试代码:
<body><s:set name="maps" value="#{'key1':'邓小平','key2':'胡锦涛','key3':'习近平'}" /><!-- 上述集合没有指定范围就表示OGNL Context范围内的变量,使用#即可 ,iterator标签中的value表示要迭代的集合--><s:iterator value="#maps"><!-- 注:Iterator标签在迭代集合时,会把当前迭代的对象放在值栈的栈顶,所以使用property标签输出时可以不用value --><s:property value="key" />=<s:property value="value" /></br></s:iterator></body>
效果:
OGNL表达式的投影功能,常用操作符:
1.?表示获得所有符合逻辑的元素。
2.^表示符合逻辑的第一个元素。
3.$表示符合逻辑的最后一个元素。
测试案例:
User对象:
public class User {private Integer uid;private String uname;private Integer age;public User() {}public User(Integer uid, String uname, Integer age) {this.uid = uid;this.uname = uname;this.age = age;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}}
UserAction.java:
/** * 在请求访问action的时候,系统会迅速创建ActionContext->valueStack->action * 并且把action存放在valueStack中,这就是为什么OGNL表达式可以直接以属性名称的方式访问属性。 * 因为action存放在了valueStack中。 * 这个类中的users属性可以直接通过属性名称的方式访问 * @author Liao * */public class UserAction extends ActionSupport {private static final long serialVersionUID = 1L;private List<User> users;public List<User> getUsers() {return users;}public void setUsers(List<User> users) {this.users = users;}public String execute(){users = new ArrayList<User>();users.add(new User(1, "习近平", 20));users.add(new User(1, "胡锦涛", 30));users.add(new User(1, "邓小平", 40));return this.SUCCESS;}}
前台投影测试:
<body><!-- users是action中的属性,即存放在ValueStack中,所以访问users不需要使用#命名空间的形式 --><s:iterator value="users.{?#this.age > 30}"><s:property value="uname" />:<s:property value="age" /></br></s:iterator></body>
注:users是action中的属性,当然也是ValueStack中的对象,所以可以用属性名称的方式直接访问。在上述代码中,直接在集合后紧跟.{}运算符表明用于取出该集合的子集,{}的表达式用于获取符合条件的元素,this指的是为了从大集合users帅选数据到小集合,需要对大集合users进行迭代,this代表当前迭代的元素。
效果:
iterator标签中的status属性用来指定迭代时的IteratorStatus实例,该方法包含如下集合方法:
int getCount(),返回当前迭代了几个元素。
int getIndex(),返回当前迭代元素的索引。
boolean isEven(),返回当前被迭代元素的索引是否是偶数
boolean isOdd(),返回当前被迭代元素的索引是否是奇数
boolean isFirst(),返回当前被迭代元素是否是第一个元素。
boolean isLast(),返回当前被迭代元素是否是最后一个元素。
有了这些方法,我么可以做一些特殊效果:
测试代码:
<body><s:set name="list" value="{'邓小平','胡锦涛','习近平'}" /><s:iterator value="#list" status="s"><!-- 如果是奇数就为红色,否则为蓝色 --><font color=<s:if test="#s.odd">red</s:if><s:else>blue</s:else>><s:property/></font></s:iterator> </body>
效果:
参数:
测试代1:
<body> <s:set name="age" value="22"></s:set> <!-- 使用ognl接收值 --> <s:if test="#age > 20"> 您的青春已经让狗给吃了! </s:if> <s:elseif test="#age > 35"> 七年之痒,勿出轨! </s:elseif> <s:else> 青春年华,无限风光! </s:else> </body>
效果:
OGNL表达式可以使用in和not in两个元素符号,in表达式用来判断某个元素是否在指定的集合对象中,not in判断某个元素是否不在某个集合对象中。
测试代码2:
<body> <!-- OGNL表达式in的测试 --> <s:if test="'liao' in {'liao','zhong','min'}"> 您中大奖啦! </s:if> <s:else> 您被坑啦! </s:else> <!-- OGNL表达式not in的测试 --> <s:if test="'liao' not in {'lavimer','hello'}"> 你不在啊! </s:if> <s:else> 你在啊! </s:else> </body>
注:<s:select>下拉框、<s:checkboxlist>复选框、<s:radio>单选框在Web开发中经常使用,将在后面的文章中以专题的形式详细讨论。
- struts2标签和OGNL表达式
- ognl表达式和struts2标签
- ognl表达式和struts2标签
- OGNL表达式和Struts2标签
- struts2标签和ognl表达式
- Struts2 - OGNL表达式和Struts2标签库
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- OGNL表达式struts2标签“%,#,$”
- 2014年东北地区Oracle杯
- 函数有括号与没括号的区别 -- f1与f1()的区别
- lynis—*nix安全审计工具
- Linux下配置phpMyAdmin
- C++ GUI QT 第4版 第二章 2.3(3)
- OGNL表达式和Struts2标签
- Don't mention it 与 forget it 的区别
- Xcode 5 + iOS 7免证书(iDP)真机调试与生成IPA全攻略
- LeetCode Count and Say
- 好卡不方便看电视不过考试不挂科上百个
- plist 如何换行
- 一个伟大、孤僻、特立独行的灵魂:天才已去60年
- 程序员必读的书刊收藏
- 海盗分赃算法题