`

《研磨struts2》第七章 值栈和OGNL 之 7.3 使用OGNL访问复杂对象

 
阅读更多

7.3  使用OGNL访问复杂对象

7.3.1  访问域对象

通过ognl访问域对象,这件事情其实在好早以前,我们就已经做过了,只是那个时候不知道罢了,还是来示例一下。

(1)先来准备一个域对象,很简单,只有两个属性,代码示例如下:

 

java代码:
  1. package cn.javass.ognl.vo;  
  2. public class UserModel {  
  3.     private String userId;  
  4.     private String name;  
  5.     public String getUserId() {  
  6.         return userId;  
  7.     }  
  8.     public void setUserId(String userId) {  
  9.         this.userId = userId;  
  10.     }  
  11.     public String getName() {  
  12.         return name;  
  13.     }  
  14.     public void setName(String name) {  
  15.         this.name = name;  
  16.     }  
  17. }  

(2)写一个新的Action,定义一个UserModel类型的属性,并给出对应的getter/setter,然后在execute方法中对其进行赋值:

 

java代码:
  1. package cn.javass.ognl.action;  
  2.   
  3. import cn.javass.ognl.vo.UserModel;  
  4. import com.opensymphony.xwork2.ActionSupport;  
  5.   
  6. public class OgnlAction extends ActionSupport{  
  7.     private UserModel um = new UserModel();  
  8.     public UserModel getUm() {  
  9.         return um;  
  10.     }  
  11.     public void setUm(UserModel um) {  
  12.         this.um = um;  
  13.     }  
  14.       
  15.     public String execute(){  
  16.         System.out.println("您输入的用户编号="+um.getUserId());  
  17.         System.out.println("您输入的用户姓名="+um.getName());  
  18.         um.setUserId("在action中修改了UserId");  
  19.         um.setName("在action中修改了name");  
  20.         return this.SUCCESS;  
  21.     }  
  22. }  

(3)在struts.xml中的配置很简单,示例如下:

 

java代码:
  1. <action name="ognlAction" class="cn.javass.ognl.action.OgnlAction">  
  2.             <result>/ognl/result.jsp</result>  
  3.         </action>  

(4)作一个用户新增的页面,示例如下:

 

java代码:
  1. <form action="/helloworld/ognlAction.action" method="post">  
  2.     用户编号:<input type="text" name="um.userId"><br>  
  3.     用户姓名:<input type="text" name="um.name"><br>  
  4.     <input type="submit" value="提交">  
  5. </form>  

(5)然后制作一个结果页面,新增成功过后跳转到这个页面,示例如下:

 

java代码:
  1. <%@ taglib prefix="s" uri="/struts-tags"%>  
  2. 用户编号为: <s:property value="um.userId"/>  
  3. <br>  
  4. 用户姓名为: <s:property value="um.name"/>  

(6)运行测试一下看看,新增页面如下图所示:

图7.4  新增页面

点击提交按钮过后,会跳转到结果页面,如下图所示:

 


图7.5  新增后的结果页面

此时后台输出如下所示:

 

java代码:
  1. 您输入的用户编号=u1  
  2. 您输入的用户姓名=张三  

(7)小结

       在这里要强调两点:

  • getter/setter方法优先

什么意思呢?

就是说如果属性有对应的getter/setter方法,其实OGNL在对应的时候,是先对应getter/setter方法,如果getter/setter方法已经对应上了,那就不会对应属性了。

比如上例中的“um.userId”这个OGNL中的“um”,在访问的时候,并不是直接访问的OgnlAction中的um这个属性,而是先去对应getUm和setUm方法,只有getter/setter对应不上,才去访问属性,当然,直接访问属性的时候需要属性的访问权限为public。

来示范一下,先把Action中对应um的getter/setter方法修改一下,示例如下:

 

java代码:
  1. public class OgnlAction extends ActionSupport{  
  2.     private UserModel um = new UserModel();  
  3.   
  4.     public UserModel getUm1() {  
  5.         return um;  
  6.     }  
  7.     public void setUm1(UserModel um) {  
  8.         this.um = um;  
  9.     }  
  10.       
  11.     public String execute(){  
  12.         System.out.println("您输入的用户编号="+um.getUserId());  
  13.         System.out.println("您输入的用户姓名="+um.getName());  
  14.         um.setUserId("在action中修改了UserId");  
  15.         um.setName("在action中修改了name");  
  16.         return this.SUCCESS;  
  17.     }  
  18. }  

再去测试看看,会发现后台和结果页面都没有能够取到值,为什么呢?

       因为优先对应getter/setter方法,我们在新增页面里面写的是“um.userId”,也就是优先对应getUm和setUm方法,由于我们把方法名称改掉了,对应不上,那么就去对应属性,可是,um属性是私有的,也对应不到,于是就没有能跟这个OGNL表达式对应的东西,所以值也就为null了。

       把新增页面中的“um.userId”改为“um1.userId”,“um.name”改为“um1.name”,同理去修改结果页面的表达式,再次运行测试,会发现后台和结果页面都能够取到值了。

  • 私有属性 vs 公有属性。

在前面的例子中使用了私有属性um,及其对应的getter/setter,其实也可以直接定义一个public的属性,但是请注意,声明公有属性的时候,必须在声明的时候直接初始化,否则会报错,如:

 

java代码:
  1. public UserModel um = new UserModel();  

其实两种写法是等价的。

7.3.2  访问List或数组

通过ognl访问数组或List的时候,只需要指明索引即可访问数组或List中的指定元素。

(1)首先,来修改一下OgnlAction,声明一个List类型的属性及其getter/setter,并在execute方法中对其设置值,示例代码如下:

 

java代码:
  1. package cn.javass.ognl.action;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import cn.javass.ognl.vo.UserModel;  
  5. import com.opensymphony.xwork2.ActionSupport;  
  6.   
  7. public class OgnlAction extends ActionSupport{  
  8.     private List<UserModel> umList = new ArrayList<UserModel>();  
  9.     public List<UserModel> getUmList() {  
  10.         return umList;  
  11.     }  
  12.     public void setUmList(List<UserModel> umList) {  
  13.         this.umList = umList;  
  14.     }     
  15.       
  16.     public String execute(){  
  17.         System.out.println("您输入的用户编号="+umList.get(0).getUserId());  
  18.         System.out.println("您输入的用户姓名="+umList.get(0).getName());  
  19.         UserModel um = new UserModel();  
  20.         um.setUserId("在action中修改了UserId");  
  21.         um.setName("在action中修改了name");  
  22.           
  23.         umList.add(um);  
  24.         return this.SUCCESS;  
  25.     }     
  26. }  

(2)这时候,Action中有一个名为umList属性,在外界引用的时候,需要用索引来引用。比如新增页面,修改示例如下:

 

java代码:
  1. <form action="/helloworld/ognlAction.action" method="post">  
  2.     用户编号:<input type="text" name="umList[0].userId"><br>  
  3.     用户姓名:<input type="text" name="umList[0].name"><br>  
  4.     <input type="submit" value="提交">  
  5. </form>  

(3)而结果页面也需要做相应的修改,示例如下:

 

java代码:
  1. <%@ taglib prefix="s" uri="/struts-tags"%>  
  2. 用户编号为: <s:property value="umList[0].userId"/>  
  3. <br>  
  4. 用户姓名为: <s:property value="umList[0].name"/>  

(4)去运行测试看看,后台或者结果页面都应该能够正确获取值。

(5)把List类型换成数组类型,访问方式和写法基本类似。但是要注意一个问题,就是换成数组类型过后,必须在OGNL访问之前要初始化索引所对应的对象,最简单的方法就是在定义的时候直接初始化,示例如下:

 

java代码:
  1. public class OgnlAction extends ActionSupport{  
  2.     private UserModel[] umList = {new UserModel(),new UserModel()};  
  3.     public UserModel[] getUmList() {  
  4.         return umList;  
  5.     }  
  6.     public void setUmList(UserModel[] umList) {  
  7.         this.umList = umList;  
  8.     }     
  9.       
  10.     public String execute(){  
  11.         System.out.println("您输入的用户编号="+umList[0].getUserId());  
  12.         System.out.println("您输入的用户姓名="+umList[0].getName());  
  13.         UserModel um = new UserModel();  
  14.         um.setUserId("在action中修改了UserId");  
  15.         um.setName("在action中修改了name");  
  16.           
  17.         umList[0] = um;  
  18.         return this.SUCCESS;  
  19.     }  
  20. }  

如果没有在OGNL访问前进行初始化,那么会报出“NullPointerException”的例外。

(6)还可以访问数组的length属性,也可以访问集合的方法,比如:

  • OGNL表达式为:array.length,就表示访问array这个数组的length属性
  • OGNL表达式为:list.size,就表示访问list这个集合的size()方法
  • OGNL表达式为:list.isEmpty,就表示访问list这个集合的isEmpty()方法

(7)直接在OGNL中构建集合,比如:

  • OGNL表达式为:{1,2,3},就表示构建一个包含3个值的集合,值分别是1,2,3
  • OGNL表达式为:{1,2,3}[0],就表示构建一个包含3个值的集合,值分别是1,2,3 ,然后获取索引为0的值,也就是1了。

7.3.3  访问Map

通过ognl访问Map的时候,通常的格式为“Map名称[‘键的名称’]”,当然也可以用“Map名称.键的名称”的方式来访问Map中的值,但建议使用前面一种方式。

(1)对OgnlAction稍作修改来示范,声明一个Map类型的属性及其getter/setter,并在execute方法中对其初始化:

 

java代码:
  1. public class OgnlAction extends ActionSupport{  
  2.     private Map<String,UserModel> userMap = new HashMap<String,UserModel>();  
  3.     public Map<String, UserModel> getUserMap() {  
  4.         return userMap;  
  5.     }  
  6.     public void setUserMap(Map<String, UserModel> userMap) {  
  7.         this.userMap = userMap;  
  8.     }  
  9.       
  10.     public String execute(){  
  11.         System.out.println("您输入的用户编号="+userMap.get("umtest").getUserId());  
  12.         System.out.println("您输入的用户姓名="+userMap.get("umtest").getName());  
  13.         UserModel um = new UserModel();  
  14.         um.setUserId("在action中修改了UserId");  
  15.         um.setName("在action中修改了name");  
  16.           
  17.         userMap.put("umtest",um);  
  18.         return this.SUCCESS;  
  19.     }  
  20. }  

(2)修改新增页面的OGNL表达式,示例如下:

 

java代码:
  1. <form action="/helloworld/ognlAction.action" method="post">  
  2.     用户编号:<input type="text" name="userMap['umtest'].userId"><br>  
  3.     用户姓名:<input type="text" name="userMap['umtest'].name"><br>  
  4.     <input type="submit" value="提交">  
  5. </form>  

(3)修改结果页面的OGNL表达式,示例如下:

 

java代码:
  1. <%@ taglib prefix="s" uri="/struts-tags"%>  
  2. 用户编号为: <s:property value="userMap['umtest'].userId"/>  
  3. <br>  
  4. 用户姓名为: <s:property value="userMap['umtest'].name"/>  

(4)去运行测试看看,结果页面和后台应该都能正确地获取到值了。

(5)还可以访问Map的方法,比如:

  • OGNL表达式为:map.size,就表示访问map这个Map的size()方法
  • OGNL表达式为:map.isEmpty,就表示访问map这个Map的isEmpty()方法

(6)也可以直接在OGNL中构建Map,比如:

  • OGNL表达式为:#{'one':'aa','two':'bb'},就表示构建一个包含2组值的Map,key值分别是one和two,对应的值分别是aa和bb
  • OGNL表达式为:#{'one':'aa','two':'bb'}['one'],就表示构建一个包含2组值的Map,key值分别是one和two,对应的值分别是aa和bb,然后获取key为one的值,也就是aa了。

7.3.4  组合使用

通过前面的讲述,你可以发现,OGNL可以访问不同的对象、属性和方法,那么可不可以把这些复杂的对象结构组合起来,让OGNL去访问呢?

假如在Session中,有一个List作为Session的属性,对应的key值是“users”,List里面放的全是UserModel类型的对象,现在要访问其中的第3个元素的userId属性,应该怎样用OGNL去访问呢?

       回答这个问题需要层层分解,一步一步来:

  • 要获取Session中一个key值为“users”的List,对应的OGNL应为#session[‘users’],或者#session.users
  • 要操作这个List的第3个元素,对应的OGNL应为#session[‘users’][2],或者#session.users[2]
  • 要操作这个对象的userId属性,对应的OGNL应为#session[‘users’][2].userId,或者#session.users[2].userId

这样,就得到了最终的OGNL,可以去测试一下,看看好用不。

       OGNL本身有很多的知识,这里只是介绍了OGNL中最常用的知识,更多的知识可以去http://www.ognl.org查看,那里有很详细的文档。

 

私塾在线网站原创《研磨struts2》系列

转自请注明出处:【http://sishuok.com/forum/blogPost/list/0/4070.html

欢迎访问http://sishuok.com获取更多内容

3
2
分享到:
评论

相关推荐

    struts2--3.Ognl与值栈

    在实际开发中,了解并熟练掌握OGNL和值栈的使用,能显著提高Struts2应用的开发效率和代码可维护性。通过阅读`struts_3`和`struts3_web`这两个文件,你可以进一步深入学习Struts2框架的这些关键特性,并通过实践加深...

    struts2中的OGNL的源码

    6. **安全机制**:为了防止OGNL注入攻击,Struts2提供了安全配置,限制可以访问的对象和属性。 源码阅读可以帮助我们了解OGNL的工作原理,如如何解析表达式,如何找到正确的ValueResolver,以及如何处理上下文中的...

    Struts2_OGNL

    值栈是Struts2框架中的核心概念之一,它是一个用于临时存储对象的栈结构,这些对象包括Action实例、模型对象、临时对象等。值栈中的对象可以按照以下四种类型划分: 1. 栈顶对象:在程序执行过程中,由容器自动创建...

    Struts2 使用OGNL表达式

    OGNL是Struts2的核心组件之一,它允许开发者通过简单的字符串表达式来访问和修改对象的属性,甚至可以处理复杂的对象结构。以下是一些关于Struts2中OGNL表达式的关键知识点: 1. **基础语法**:OGNL表达式的格式...

    struts2 ognl用法项目

    1. **值栈访问**:Struts2使用值栈存储请求中的所有对象,OGNL可以从值栈顶部找到并访问对象。例如,`#request.user.name`表示从HTTP请求对象中获取`user`属性的`name`。 2. **动态方法调用**:OGNL支持直接调用...

    Struts2核心包ognl-2的源代码

    其中,OGNL(Object-Graph Navigation Language)是Struts2中的一个关键组件,它是一种强大的表达式语言,用于在运行时访问和操作对象的属性。这个压缩包包含的是OGNL的2版本的源代码,这对于理解Struts2框架的工作...

    struts2 ognl的用法

    OGNL作为Struts2框架的核心技术之一,其强大的表达能力和灵活的使用方式极大地提高了开发效率。理解并熟练掌握OGNL的使用,对于深入学习和高效开发基于Struts2的应用程序至关重要。通过本文对OGNL在Struts2中的应用...

    Struts2深入学习----OGNL表达式原理

    在Struts2的ActionContext中,OGNL查找值栈(ValueStack),这是一个存储所有请求相关对象的数据结构。值栈顶部的对象通常为Action实例,OGNL表达式会在此对象及其关联的对象图中查找属性。 Struts2的标签库也广泛...

    OGNL访问OGNL上下文和Action上下文Struts2rarfdsafsdfasdfas

    在Struts2中,OGNL(Object-Graph Navigation Language)是一种表达式语言,用于访问和操作对象的属性。OGNL上下文(OGNL Context)和Action上下文是Struts2中两个重要的概念,它们对于理解和使用OGNL表达式至关重要...

    struts2中的ognl

    使用OGNL时,通常配合Struts2的标签,比如`s:property`,通过值栈来访问和显示数据。 3. **EL与值栈的区别**: - Expression Language(EL)虽然也能访问值栈,但它只能从栈顶开始查找,而OGNL可以更灵活地遍历...

    struts2 标签 OGNL

    在Struts2中,OGNL被广泛用于访问Action中的属性,以及在视图层(如JSP)中绑定和操作数据。 首先,OGNL使得访问对象属性变得非常直观。它支持点符号(.)和方括号([''])两种方式来访问属性。例如,如果在Action...

    struts2 OGNL表达式使用

    OGNL(Object-Graph Navigation Language)是对象图导航语言,允许开发者在Struts2应用程序中访问和操作对象及其属性。下面是OGNL表达式的使用方法: 访问基本属性 1. 访问值栈中action的普通属性: 2. 访问值栈中...

    struts2 中 OGNL表达式的使用

    struts2 中 OGNL表达式的使用struts2 中 OGNL表达式的使用

    Struts2之Ognl详解案例TextOgnl

    OGNL是用于Java对象图形导航的语言,它可以轻松地访问和操作复杂的对象结构。在Struts2中,OGNL主要用作视图层与模型层之间的数据绑定工具,使得开发者能够方便地在JSP页面中动态地访问Action类的属性。 二、OGNL的...

    struts2 OGNL之&lt;s:property&gt;标签访问值栈(value stack)用法

    值栈是Struts2中一个核心的概念,它是一个存储用户请求数据和应用状态的对象栈。 OGNL是一种表达式语言,用于获取和设置Java对象的属性。在Struts2中,OGNL被广泛用于视图层,允许开发者直接在JSP页面上访问模型...

    ognl.rar_OGNL API_struts2 ognl api_struts2帮助文档

    3. **ValueStack**:Struts2的ValueStack是一个对象栈,它用于存放Action实例和其他数据。OGNL可以方便地从ValueStack中查找和操作对象。 4. **OGNL表达式求值器(Evaluator)**:负责解析和执行OGNL表达式,返回...

    Struts2的标签库及OGNL表达式语言

    Struts2是一个流行的Java web开发框架,其核心特性之一就是使用OGNL(Object-Graph Navigation Language)作为表达式语言,并提供了丰富的标签库来简化视图层的开发。本篇文章将详细探讨Struts2中的OGNL表达式语言...

    Struts2 ognl

    OGNL是一个轻量级的表达式语言,它的主要功能是获取和设置对象属性,支持复杂的运算符和函数调用,使得开发者能够在模板中灵活地访问和操作模型数据。在Struts2中,OGNL作为视图层与控制器层之间的桥梁,负责解析和...

    struts2-OGNL表达式测试

    2. **值栈操作**:Struts2使用值栈存储请求相关的数据。OGNL可以直接访问值栈中的任何对象,例如`&lt;s:property value="#session.user.name" /&gt;`将显示会话中用户对象的姓名。 3. **动态方法调用**:OGNL支持对对象的...

    Struts2 如何使用OGNL表达式(三十八)

    首先,OGNL是Struts2的核心组成部分,它允许开发者在Action类和JSP页面之间灵活地传递和访问数据。在Action类中,你可以设置属性,然后在JSP页面上通过OGNL表达式来访问这些属性。例如,如果有一个`User`对象,其...

Global site tag (gtag.js) - Google Analytics