浏览 2848 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-09-26
WebWork的EL-对象图导航语言(Object Graph Navigation Language, 缩写为OGNL)是作为Web页面脚本的最佳选择。 一. 基本特性 1. 访问bean属性 根据JavaBean的规范,bean属性使用诸如getXxx(), setXxx(), isXxx()或者hasXxx()这样标准形式的getter方法或 setter方法。其中, isXxx()和hasXxx()形式用于boolean属性。在WebWork中,访问这些属性(不管是获取数据还是 设置数据)都使用形式为xxx的属性引用。 示例: a. action package ch8; import ch4.User; import com.opensymphony.xwork.ActionSupport; public class OgnlTest extends ActionSupport{ private User user; public String execute() { user = new User(); user.setName("zs"); user.setPassword("password"); return SUCCESS; } //setter和getter方法 } b. result <action name="ognlTest" class="ch8.OgnlTest"> <result name="success">ognl.jsp</result> </action> c. jsp <%@page contentType="text/html;charset=UTF-8" %> <%@taglib uri="webwork" prefix="ww" %> <html> <body> <ww:property value="user.name"/> <!--其中value中内容为ognl表达式--> <ww:property value="user.password"/> </body> </html> 2. 常量 OGNL表达式常量与EL类型, 常量类型 范例 ------------ -------------- char 'a' String "hello world" boolean true false 另String常量可以使用单引号或双引号括起来,示例: <ww:property value="\"a\""/>并不等同于 <ww:property value='a'/> 3. 操作符 OGNL支持所有Java操作 运算 范例 ------------ -------------- 递增 ++foo 递减 foo++ 等于 foo == bar 不等于 foo != bar in foo in someList not in foo not in someList 赋值(=) foo = 123 4. 方法调用 提供调用非属性相关的方法; 示例:假设ch4.User类中有一方法(静态方法亦可) : public String sayHello() { return "hello world"; } 使用以下形式可以在浏览器上输出:hello world <ww:property value="user.sayHello()"/> 5. 设置数值及表达式列表 在单条语句当中执行以逗号分隔的多个表达式,最后一个表达式的返回值作为整条语句的输出结果。 例如foo值为123,而bar值为789,则以下形式输入 789: <ww:property value="foo,bar"/> 6. 访问静态方法和类变量 使用@[className]@[Field Or Method]调用静态类变量和方法,类名必须使用包括包在内的完整类名; 示例:假设ch4.User类中有一方法(静态方法亦可) : public static String sayHello() { return "hello world"; } 使用以下形式可以在浏览器上输出:hello world <ww:property value="@ch4.User@sayHello()"/> 另OGNL也可使用vs(vs代表Value Stack,就是值栈)前缀调用保存于值栈中的类的静态属性和静态方法; <ww:property value="@vs@sayHello()"/> 一般来说,只有在一直了解值栈中包含什么对象的情况下,使用vs的形式才是有用的,否则建议使用完整的包 名和类名比较好。 7. 访问OGNL上下文及ActionContext 示例: Java代码: OGNL表达式 ------------------------------------------------------- --------------------- ActionContext().getContext().getParameters() #parameters ActionContext().getContext().getParameters().size() #parameters.size ((Kermit)ActionContext().getContext().get("kermit")).getAge() #kermit.age WebWork中另提供一些更短标识符方便访问: . parameters : 一个包含当前请求中所有HttpServletRequest参数的map; . request : 一个包含当前请求中所有HttpServletRequest属性的map; . session : 一个包含当前请求中所有HttpSession属性的map; . application: 一个包含当前请求中所有ServletContext属性的map; . attr : 一个依次从请求、会话和应用程序的Map中搜索属性的map; 示例: a. action package ch8; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import com.opensymphony.webwork.interceptor.ServletRequestAware; import com.opensymphony.xwork.ActionSupport; public class ScopeTest extends ActionSupport implements ServletRequestAware{ private HttpServletRequest request; @Override public void setServletRequest(HttpServletRequest arg0) { request = arg0; } @Override public String execute() { HttpSession session = request.getSession(); ServletContext context = session.getServletContext(); request.setAttribute("req","request0"); session.setAttribute("ses","session1"); context.setAttribute("app","application2"); return SUCCESS; } } b. result <action name="scopeTest" class="ch8.ScopeTest"> <result name="success">scopeTest.jsp</result> </action> c. jsp <%@page contentType="text/html;charset=UTF-8" %> <%@taglib uri="webwork" prefix="ww" %> Request parameter: <ww:property value="#parameters['name']"/><br> Request attribute: <ww:property value="#request['req']"/><br> Session attribute: <ww:property value="#session.ses"/><br> Application attribute: <ww:property value="#application.app"/><br> Request attribute: <ww:property value="#attr.req"/><br> Session attribute: <ww:property value="#attr.ses"/><br> Application attribute: <ww:property value="#attr.app"/><br> 二. 操作集合(Collections) 1. 操作列表(list)和数组(array) Java代码 OGNL表达式 ------------------------- ---------------------------------- list.get(0) list[0] array[0] array[0] ((User)list.get(0)).getName() list[0].name array.length array.length list.size() list.size list.isEmpty() list.isEmpty 除了访问列表的数值外,OGNL还可以动态地创建列表:使用大括号将元素括起来,元素间使用逗号分隔。 Java代码 OGNL表达式 ------------------------- ---------------------------------- List list = new ArrayList(3); {1,3,5} list.add(1); list.add(3); list.add(5); return list; ------------------------- ---------------------------------- List list = new ArrayList(2); {"foo","bar"}[1] list.add("foo"); list.add("bar"); return list.get(1); 2. 操作Map Java代码 OGNL表达式 ------------------------- ---------------------------------- map.get("foo") map['foo'] map.get(new Integer(1)) map[1] User user = (User)map.get("zs"); map['zs'].name return user.getName(); map.put("foo","bar"); map['foo']='bar' map.size(); map.size map.isEmpty(); map.isEmpty 除了访问Map的数值外,OGNL还可以动态地创建Map。必须在左边的大括号之前放置一个#号。 Java代码 OGNL表达式 ------------------------- ---------------------------------- Map map = new HashMap(2); #{"foo":"bar","baz":"whazzit"} map.put("foo","bar"); map.put("baz","whazzit"); return map; Map map = new HashMap(2); #{1:"one",2:"two"} map.put(new Integer(1),"one"); map.put(new Integer(2),"two"); return map; Map map = new HashMap(2); #{#user1.name:#user1.mother.name, map.put(user1.getName(),user1.getMother() #user2.name:#user2.mother.name} .getName()); map.put(user2.getName(),user2.getMother() .getName()); return map; ActionContext.getContext(). #parameters['id'] getParameters().get("id"); String name = user.getName(); #session["user-"+name] Map map = ActionContext.getContext() .getSession(); return map.get("user-"+name); session.put("user",user); #session['user'] = user 3. 对集合进行筛选(filtering)和投影(projecting) 筛选:以一个集合为基础生成一个新集合的技术,而新集合中只包含可以通过筛选的对象。语法: collection.{? expression} 以上expression是真正意义上的筛选器, 会对集合中的每个对象进行求值。而#this这个特殊的变量 则是用于标识正在进行求值的对象。例,要从Kemit的孩子们中筛选出年龄等于2或者小于2的孩子,表 达式为: #this.age <= 2 投影:根据投影规则对集合中的元素进行转换。语法: collection.{ expression } 其中expression用来对原始集合中被循环迭代到的对象进行求值。 筛选返回的集合中的元素与原始集合中的是一样的,但数量有可能要少; 投影返回的集合中的元素与原始集合中的有可能不一样,但数量一样多; 示例: OGNL表达式 描述 ------------------------- ---------------------------------- children.{name} 投影的结果为所有孩子的姓名 children.{?#this.age > 2} 筛选的结果为年龄大于2的孩子 children.{?#this.age<=2}.{name} 选筛选出年龄小于等于2的孩子,再对结果列进行投影操作,得 到孩子的名字 children.{name +'->'+mother.name} 投影的结果为符合"名字->母亲名字"样式的字符串列表 4. "#"的多种用途 . 引用ActionContext中的值: #foo . 动态构建Map #{1:'one',2:'two'} . 对集合进行筛选和投影操作 children.{?#this.age > 2} 三. 表达式语言的高级特性 正是这些高级特性令WebWork能够在众多的MVC框架中脱颖而出。 1. 将值栈和表达式语言联系起来 在WebWork中,整个值栈就是上下文(context)中的根对象。WebWork提供了与OGNL特别的集成:根据表达式自动查找整 个栈(从上而下),直至找到了一个包含了所需的属性的对象。 举例:栈中有两个对象:Muppet和Person,两个对象都有name属性;Muppet有lifeSized属性而Person有salary属性。 Muppet对象在栈顶,而Person对象在其下面。如下图: ------------------------------------- | Muppet | | ------------ | | name | | lifeSized | | | | Person | | ------------ | | name | | salary | | | | | ------------------------------------- OGNL表达式 描述 ------------------------- ---------------------------------- lifeSized 调用muppet.isLifeSized() salary 调用person.getSalary() name 因为muppet位于person之上,所以调用muppet.getName() [1].name 由于[1]这个语法指明了WebWork将从位置1开始往下查找,所以 调用person.getName(); top 返回muppet [1].top 由于[1]返回的是一个范围较小的值栈,而表达式top是基于它的, 所以整个表达式返回结果是person。因person位于这个新的,范围 较小的值栈的顶部。 2. 数据类型转换 OGNL表达式 描述 ------------------------- ---------------------------------- #kermit.age = "25" 为一个int型变量设置String值,该String值随后会被转换为25 #kermit.name = 25 为一个String型变量设置int值,该int值随后会被转为"25" 3. 处理null属性的访问 OGNL在检测出访问了一个null对象的属性时,就会提供一种方式将null对象转化为真实对象。 4. 动态创建lambda表达式 定义语法::[...] lambda表达式只能使用一个参数,该参数可通过#this引用。示例: #isKermit = :[#this.name == @vs@OG_MUPPET ? true : false] 定义好之后,可将其置于OGNL上下文中,然后通过以下形式调用: OGNL表达式 描述 ------------------------- ---------------------------------- #isKermit(top) 判断位于栈顶的对象是否拥有Kermit这样的名字; #isKermit(#kermit) kermit是Kermit类型吗? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-07-23
顶邓老师 顶邓老师
|
|
返回顶楼 | |