struts2的ognl表达式学习心得

   经过一段时间的闭关练习,终于对struts2有所了解.其实struts2并不难,一看就能明白其中奥妙.我对struts2的验证体系保留怀疑态度,因为它的验证消息使用标签打在页面上,实在太丑,在真实项目中不知道是否有人这么做.也许是我太菜了,还不知道如何将验证消息显示得更友好,希望各位不吝拍砖指导.
  然而,我认为struts2最复杂难学的是它内置的ognl表达式.这个ognl在我开始学struts2时,让我云里雾里,不知如何应对.经过几轮的翻看书籍,与网上资料查询,还算是让我有所明白一点.在此记录,以便日后温习,同时,如果这篇文章对各位有哪怕一点帮助,那便是我最大的荣幸.
  首先,要知道ognl最主要的功能就是取数据,它可以利用一段简短的表达式取出各种各样丰富的数据.其次,它还附带了一些便捷的功能,如:方法调用、静态方法和属性调用、数值运算……我们最关心的是如何取数据,因此,接下来我将重点介绍如何取数据,至于附带功能将不做介绍。
  知道了ognl最主要的功能是取数据后,那么数据从哪里取呢!ognl会从两个地方取:一个是Action的实例属性;另一个是ValueStack(中文名叫值栈)。ognl会先从前者里面取,如果没取到再到ValueStack里取。Action的实例属性好理解,但这个ValueStack从字面上看,着实不好理解,以致于我将struts2的源码引进eclipse里,单步调试才算有所启发。可以将ValueStack初步理解为一个map,在这个map里存储了request、session、application、response、action实例、parameters数组……还有很多你不知道的对象。有了这个map,还愁数据取不到吗。
  注意:将ValueStack初步理解为一个map,只适于初学struts2的人,其实它内部并没这么简单。由于水平、时间有限,我并不能掌握其内部精髓,加上表达能力不佳,怕表达不对误导大家,所以我们姑且理解ValueStack为一个map吧。如果想更深的了解的ValueStack,请查看struts2的源码。

  接下来,便是取数据。取action实例的属性数据与取ValueStack中的数据不一样,先说取action实例的属性数据吧。
  action实例的属性数据可以直接在struts2的标签中通过属性名取到。如:
  注意:不要加#号。

  再是取ValueStack中的数据。
  struts2提供三种方式通过ognl表达式来取ValueStack中的数据:#、%{}、${}
  #和%{}需要放到struts2提供的标签里才生效。如:
  一、最常用的方式是:#
  1.#能取request、session、application里的attribute,但需要加前缀。如:。如果是取request范围的attribute,那么不需要加request前缀,加上反而取不到数据,ognl默认从request里取,如果没有取到并不会到session或application里取。如:
  2.#能取request里的请求参数,但必须加parameters前缀,且取到的是一个数组,所以如果你要得到参数的第一项值,那么还要加下标。如:。这相当于调用request.getParameterValues("name")[0];
  3.#加attr前缀能按request > session > application顺序获取attribute,这样当在request中取不到时,会自动向session里取,如果session里也取不到,会再向application里取。如果取到则返回,不再向上游历。如:
  4.#能构造Map,如:
  5.#能用于过滤和投影(projecting)集合,如:books.{?#this.price<100}
  以上第4、5项功能,我没有做过多介绍,因为目前为止这两项功能我使用并不多。
  二、%{}的用途是在标签的属性为字符串类型时,计算OGNL表达式的值。这个功能目前还没有深刻体会,故不介绍。
  三、${}有两个主要的用途。
  1.用于在国际化资源文件中,引用OGNL表达式。
  2.在Struts 2配置文件中,引用OGNL表达式。如 :
  
                   
        ListPhotos.action?albumId=${albumId}
   

  以上,其实主要介绍了#的使用,大部分情况下我们只与它打交道,另外两种方式需要在以后的项目中多多使用才能有所体会。
  其实,我是jstl+el的忠实粉丝,在任何项目中,只要能用上jstl标签的,我决不用其它标签。因为它是官方标准,还有它简单且已熟练,我已在众多项目中实战演练过,有了它们,我不想在使用其它标签。
  说到了这里,我还是有必要再多说两句,是不是使用了struts2,就不能再用el来取数据了呢?答案是否定的,完全可以使用el来取数据。struts2会将ValueStack里的session、application里的attribute完全复制到HttpSession、ServletContext里,这样el表达式照样能取到这两个Scope里的数据。然而,struts2并没有将ValueStack里的request里的attribute复制到HttpServletRequest,这是不是意味着el表达式就不能取request里的数据了呢?还是可以,不只可以取request里的数据,还可以取action实例的属性值。神奇吧!奥秘就在struts2对request做了封装,这个封装类是org.apache.struts2.dispatcher.StrutsRequestWrapper,它重写了getAttribute()方法,该方法先从真实的request类里取attribute,如果取到则返回,如果没有取到则从ValueStack里取,现在明白了吧!
  还有很多奥秘等着你去探索,一起加油吧!

你可能感兴趣的:(javaee)