struts2-ONGL原理和表达式

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。

 

 

OGNL表达式

  1、#号的用法

  #用法1:访问OGNL上下文和Action上下文,#相当ActionContext.getContext()

  a) 如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。

  

 1 Action中代码: 
 2  ServletActionContext.getRequest().setAttribute("username", "username_request");
 3  ServletActionContext.getServletContext().setAttribute("username", "username_application");
 4  ServletActionContext.getContext().getSession().put("username", "username_session");
 5  ValueStack valueStack=ServletActionContext.getContext().getValueStack();
 6  valueStack.set("username", "username_valueStack");
 7  
 8 Jsp页面:
 9     使用ognl表达式取值*****************************<br>
10     request:<s:property value="#request.username"/><br>
11     session:<s:property value="#session.username"/><br>
12     application:<s:property value="#application.username"/><br>
13     attr:<s:property value="#attr.username"/><br>
14     valueStack:<s:property value="username"/><br>
15     parameters:<s:property value="#parameters.cid[0]"/><br>

 

  b) OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈)。如果要访问根对象(即ValueStack)中对象的属性,则可以省略 #命名对象,直接访问该对象的属性即可。

1 Action中代码: 
2   ValueStack valueStack=ServletActionContext.getContext().getValueStack();
3   valueStack.set("msg", "msg_xxx"); 
4 Jsp页面:
5     valueStack:<s:property value="msg"/><br>

 

  c) 深入理解值栈中的 ObjectStack

  

OgnlValueStack类里有一个List类型的root变量,他存放了一组对象

处于第一位的对象叫栈顶对象。(list集合的 索引为0为栈顶)

通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,

搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。

 1 Action中代码: 
 2    ValueStack valueStack=ServletActionContext.getContext().getValueStack();
 3  
 4   //set方法放置对象到map中,map再放入到栈(List集合)上
 5   valueStack.set("student", new Student());
 6   valueStack.set("employee", new Employee());
 7 
 8   //直接放置对象到栈(List集合)上
 9   valueStack.getRoot().add(0,new Student());
10   valueStack.getRoot().add(1,new Employee());
11  
12 Jsp页面:
13      name:<s:property value="name"/><br>
14      age::<s:property value="age"/><br>
15      number::<s:property value="number"/><br>
16      salary:<s:property value="salary"/><br>

 

  #用法2:集合的投影(过滤)

   a) 集合的投影(只输出部分属性)collectionName.{ expression }

1 <s:iterator value="#request.persons.{name}" var="person">
2       <s:property value="#person"/><br>
3 </s:iterator>

  b) 集合的过滤

1) 集合的过滤有以下三种方式:
     a.“?#过滤所有符合条件的集合,如:users.{?#this.age > 19}
    
b.“^#过滤第一个符合条件的元素,如:users.{^#this.age > 19}
    
c.“$#过滤最后一个符合条件的元素,如:users.{$#this.age > 19} 
2) this   表示集合中的元素;

1 <s:iterator value="#request.persons.{?#this.age>24}" var="person">
2        <s:property value="#person"/><br>
3 </s:iterator>

  c) 集合的投影和过滤

        投影(过滤)操作返回的是一个集合,可以使用索引取得集合中指定的元素,如:users.{?#this.age > 19}[0]

1 <s:iterator value="#request.persons.{?#this.age>24}.{name}" var="person">
2       <s:property value="#person"/><br>
3 </s:iterator>

 

  #用法3:构造Map,如#{‘foo1’:‘bar1’, ‘foo2’:‘bar2’}

   这种方式常用在给radioselectcheckbox等标签赋值上 

1 jsp页面:
2       <s:radio list=“#{‘male’:‘男’,‘female’:‘女’}”  name=“sex”  label=“性别” /> 
3 运行结果是
4      <input type="radio" name="sex" id="sexmale" value="male"/>5      <input type="radio" name="sex" id="sexfemale" value="female"/>
 1 Action中的代码:
 2        Map map=new HashMap();
 3        map.put("male", "男");
 4        map.put("female", "女");
 5        ServletActionContext.getRequest().setAttribute("map", map);
 6   jsp页面:
 7         <s:radio list="#request.map" name="sex" label="性别" />
 8   运行结果是
 9         <input type="radio" name="sex" id="sexfemale" value="female"/>10         <input type=“radio” name=“sex” id=“sexmale” value=“male”>男

 

  2、%用法

  “%”符号的用途是在标签的属性值被理解为字符串类型时,告诉执行环境%{}里的是OGNL表达式。 

 1 形式一: { }中ognl表达式
 2    Action中的代码:
 3       ServletActionContext.getRequest().setAttribute("username", "username_request");                                                                           
 4    jsp页面:
 5       <s:textfield name="name" label="%{#request.username} "/>
 6   运行结果是
 7      username_request : <input type="text" name="name" value="" id="name"/>
 8 形式二: { }中值用 ’  ’引起来,这是不再是ogle表达式,而是普通的字符串
 9   jsp页面:
10       <s:textfield name="name" label="%{'foo'}"/>
11   运行结果是
12      foo : <input type="text" name="name" value="" id="name"/>

 

  3、$用法

“$”有两个主要的用途

    *  用于在国际化资源文件中,引用OGNL表达式

    *  在Struts 2配置文件中,引用OGNL表达式

1 *  用于在国际化资源文件中,引用OGNL表达式<br>
2      <s:text name="ognl" /><br><br> 

 

  resources.properties

1 ognl=${error} ognl_base
 1 在struts2配置文件中引用ognl表达式 ,引用request等作用域中的值 
 2  Action中的代码:
 3         ServletActionContext.getRequest().setAttribute("msgxx", "msg_request");
 4  struts.xml文件中
 5         <package name="ognl"   namespace="/ognl" extends="struts-default" >
 6               <action name="ognlAction_*" class="cn.itcast.ognl.OgnlAction" method="{1}">
 7                           <result name="ognl">/ognl/ongl.jsp?msg=${#request.msgxx}</result>
 8               </action>
 9         </package>
10  jsp页面:
11         parameters Msg:<s:property value="#parameters.msg[0]"/>
12  运行结果是
13         msg_request

 代码:

  1、java

 1 import java.util.Map;
 2 
 3 import javax.servlet.ServletContext;
 4 import javax.servlet.http.HttpServletRequest;
 5 
 6 import org.apache.struts2.ServletActionContext;
 7 
 8 import com.opensymphony.xwork2.ActionContext;
 9 import com.opensymphony.xwork2.ActionSupport;
10 import com.opensymphony.xwork2.util.ValueStack;
11 
12 @SuppressWarnings("serial")
13 public class OgnlAction extends ActionSupport {
14     
15     private String name = "oname";
16     
17     private String sex = "male";
18     
19     public String getName() {
20         return name;
21     }
22 
23     public void setName(String name) {
24         this.name = name;
25     }
26 
27     public String getSex() {
28         return sex;
29     }
30 
31     public void setSex(String sex) {
32         this.sex = sex;
33     }
34 
35     public String test(){
36         System.out.println("OgnlAction ************ test()");
37         
38         HttpServletRequest request = ServletActionContext.getRequest();
39         request.setAttribute("username", "username_request");
40         request.setAttribute("password", "password_request");
41         
42         Map sessionMap = ServletActionContext.getContext().getSession();
43         sessionMap.put("username", "username_session");
44         sessionMap.put("password", "password_session");
45         
46         ServletContext sc = ServletActionContext.getServletContext();
47         sc.setAttribute("username", "username_application");
48         sc.setAttribute("password", "password_application");
49         
50         //方法一:获取ValueStack对象
51         ValueStack valueStack1 = (ValueStack)request.getAttribute("struts.valueStack");
52         System.out.println("valueStack = "+valueStack1);
53         
54         /*
55          * 插入的内容,实际上是先放置在一个map集合中,又把这个map集合放置在对象栈里
56          */
57         valueStack1.set("error", "error_valueStack");
58         valueStack1.set("msg", "msg_valueStack");
59         
60         valueStack1.getRoot().add(0, new Person());
61         valueStack1.getRoot().add(0,new Employee());
62         
63         //方法二:获取ValueStack对象
64         /*ValueStack valueStack2 = ServletActionContext.getContext().getValueStack();
65         System.out.println("valueStack = "+valueStack2);*/
66         
67         return "ognl";
68     }
69     
70 }

  2、jsp

 1 <%@ page language="java" pageEncoding="utf-8"%>
 2 <%@ taglib uri="/struts-tags"   prefix="s"%>
 3 <html>
 4   <head>
 5     <title>My JSP 'index.jsp' starting page</title>
 6     <meta http-equiv="description" content="This is my page">
 7   </head>
 8   <body> 
 9      &lt;:ognl.jsp<br>
10     使用EL表达式取值-----------------------------------------<br>
11     ${requestScope.username}<br>
12     ${sessionScope.username}<br>
13     ${applicationScope.username}<br><br><br><br>
14     使用Ognl表达式取值-----------------------------------------<br>
15     1 # 如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。<br>
16     <s:property value="#request.username"/><br>
17     <s:property value="#session.username"/><br>
18     <s:property value="#application.username"/><br><br>
19     <s:property value="#request['username']"/><br>
20     <s:property value="#parameters.cid[0]"/><br>
21     <s:property value="#attr.username"/><br><br>
22     2 # 如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名对象,直接访问该对象的属性即可。<br>
23     <s:property value="msg"/><br><br>
24     深入理解值栈中的 ObjectStack<br>
25     <s:property value="name"/><br>
26     <s:property value="sex"/><br>
27     <s:property value="age"/><br>
28     <s:property value="salary"/><br><br>
29     
30     
31     用法3:构造Map<br>
32     <s:radio list="#{'01':'男','02':'女'}"></s:radio><br><br><br><br>
33     %的用法:“%”符号的用途是在标签的属性值被理解为字符串类型时,告诉执行环境%{}里的是OGNL表达式。 <br>
34     <s:property value="#request.username"/><br>
35     <s:property value="%{#request.username}"/>%{}是万能用法,无论里面的表达式是不是ognl表达式,都会强制理解为ognl表达式<br><br>
36     
37     “$”有两个主要的用途<br>
38     *  用于在国际化资源文件中,引用OGNL表达式<br>
39     <s:text name="ognl" /><br><br>
40     
41     *  在Struts 2配置文件中,引用OGNL表达式<br>
42     <s:property value="#parameters.msgxx[0]"/><br><br>
43 
44     <s:debug></s:debug>
45   </body>
46 </html>

 

 

 

posted @ 2013-05-21 18:47  hacket520  阅读(1075)  评论(0编辑  收藏  举报