分享

5、struts2值栈、命名参数与OGNL应用开发

 昵称10087950 2016-08-17

struts2中OGNL的使用

1、在Struts2中有一个称之为值栈的概念(ValueStack)

struts2值栈提供了[N]语法和TOP关键字

在struts2中,OGNL根对象就是ValueStack。在Struts2的任何流程当中,ValueStack中的最顶层对象一定是Action对象。

所以如果页面中有<s:property value="username" />这个username一定是Action中的username。

 2、struts2除了值栈,还有定义了一些“命名对象”:

parameters,#parameters.username
request,#request.username
session,#session.username
application,#application.username
attr,#sttr.username

命名对象与valuestack的关系

命名对象与ValueStack是同级的关系,而在Struts2的OGNL中,ValueStack是根元素,所以要访问request中的属性,需要#request.name。

3、访问静态方法或静态成员变量的改进。

@vs@method,如果静态方法在值栈中

4、关于Struts2标签库中OGNL的使用举例:

创建一个action:OgnlAction:

  1. import java.util.ArrayList;  
  2. import java.util.HashMap;  
  3. import java.util.List;  
  4. import java.util.Map;  
  5.   
  6. import org.apache.struts2.interceptor.ApplicationAware;  
  7. import org.apache.struts2.interceptor.RequestAware;  
  8. import org.apache.struts2.interceptor.SessionAware;  
  9.   
  10. import com.opensymphony.xwork2.ActionSupport;  
  11.   
  12. public class OgnlAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware  
  13. {  
  14.     private String username;  
  15.       
  16.     private String password;  
  17.       
  18.     private Map<String,Object> requestMap;  
  19.       
  20.     private Map<String,Object> sessionMap;  
  21.       
  22.     private Map<String,Object> applicationMap;  
  23.       
  24.     private List<Person> list;  
  25.       
  26.       
  27.       
  28.     public List<Person> getList()  
  29.     {  
  30.         return list;  
  31.     }  
  32.   
  33.     public void setList(List<Person> list)  
  34.     {  
  35.         this.list = list;  
  36.     }  
  37.   
  38.     public String getUsername()  
  39.     {  
  40.         return username;  
  41.     }  
  42.   
  43.     public void setUsername(String username)  
  44.     {  
  45.         this.username = username;  
  46.     }  
  47.   
  48.     public String getPassword()  
  49.     {  
  50.         return password;  
  51.     }  
  52.   
  53.     public void setPassword(String password)  
  54.     {  
  55.         this.password = password;  
  56.     }  
  57.   
  58.     @Override  
  59.     public void setRequest(Map<String, Object> arg0)  
  60.     {  
  61.         System.out.println("setRequest invoke!");  
  62.         this.requestMap = arg0;  
  63.     }  
  64.       
  65.     @Override  
  66.     public void setSession(Map<String, Object> arg0)  
  67.     {  
  68.         this.sessionMap = arg0;  
  69.     }  
  70.       
  71.     @Override  
  72.     public void setApplication(Map<String, Object> arg0)  
  73.     {  
  74.         this.applicationMap = arg0;  
  75.     }  
  76.       
  77.     @Override  
  78.     public String execute() throws Exception  
  79.     {  
  80.         requestMap.put("hello", "world");  
  81.         sessionMap.put("hello", "hello");  
  82.         applicationMap.put("hello", "world");  
  83.           
  84.         Cat cat1 = new Cat("cat1",20,"red");  
  85.         Cat cat2 = new Cat("Cat2",21,"yellow");  
  86.           
  87.         String[] friends1 = {"test1","test2","test3"};  
  88.         String[] friends2 = {"welcome1","welcome2","welcome3"};  
  89.           
  90.         Map<String,String> map1 = new HashMap<String,String>();  
  91.         Map<String,String> map2 = new HashMap<String,String>();  
  92.           
  93.         map1.put("test1", "test1");  
  94.         map1.put("test2", "test2");  
  95.           
  96.         map2.put("hello1", "hello1");  
  97.         map2.put("hello2", "hello2");  
  98.           
  99.         Person person1 = new Person("zhangsan",20,"beijing",friends1,cat1,map1);  
  100.         Person person2 = new Person("lisi",22,"shanghai",friends2,cat2,map2);  
  101.           
  102.         list = new ArrayList();  
  103.           
  104.         list.add(person1);  
  105.         list.add(person2);  
  106.           
  107.         return SUCCESS;  
  108.     }  
  109. }  


这个action实现了三个接口:RequestAware,SessionAware,ApplicationAware,这是一个知识点,这三个接口中都提供了一个类似的方法:
setRequest(Map<String, Object> arg0);setSession(Map<String, Object> arg0);setApplication(Map<String, Object> arg0),在struts2的众多过滤器中,有一个过滤器对请求的Action进行检查,看是否实现了上述三个接口,如果实现了,就会自动调用其中的setXXX方法,将相应的request、session、application对象保存。这是访问request等对象的又一种方法。

struts配置文件进行相应的action配置:

  1. <action name="OgnlAction" class="com.cdtax.action.ognl.OgnlAction">  
  2.             <result name="success">ognl.jsp</result>  
  3.         </action>  

然后创建一个ognl.jsp测试页面:

  1. <%@ page language="java" import="java.util.*,com.cdtax.action.ognl.*,com.opensymphony.xwork2.*,com.opensymphony.xwork2.util.*" pageEncoding="UTF-8"%>  
  2. <%@ taglib prefix="s" uri="/struts-tags" %>  
  3.   
  4. <%  
  5. String path = request.getContextPath();  
  6. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  7. %>  
  8.   
  9. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  10. <html>  
  11.   <head>  
  12.     <base href="<%=basePath%>">  
  13.       
  14.     <title>My JSP 'ognl.jsp' starting page</title>  
  15.       
  16.     <meta http-equiv="pragma" content="no-cache">  
  17.     <meta http-equiv="cache-control" content="no-cache">  
  18.     <meta http-equiv="expires" content="0">      
  19.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  20.     <meta http-equiv="description" content="This is my page">  
  21.     <!-- 
  22.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  23.     -->  
  24.   
  25.   </head>  
  26.     
  27.   <body>  
  28.     username:<s:property value="username"/><br/>  
  29.     password:<s:property value="password"/><br/>   
  30.     _________________________________________________________<br/>  
  31.       
  32.     username:<s:property value="#parameters.username"/><br/>  
  33.     password:<s:property value="#parameters.password"/><br/>  
  34.     _________________________________________________________<br/>  
  35.       
  36.     request:<s:property value="#request.hello"/><br/>  
  37.     session:<s:property value="#session.hello"/><br/>  
  38.     application:<s:property value="#application.hello"/><br/>  
  39.         _________________________________________________________<br/>  
  40.       
  41.     request:<%= ((Map)ActionContext.getContext().get("request")).get("hello") %><br/>  
  42.     session:<%= ActionContext.getContext().getSession().get("hello") %><br/>  
  43.     application:<%= ActionContext.getContext().getApplication().get("hello") %><br/>  
  44.       
  45.     attr:<%= ((Map)ActionContext.getContext().get("attr")).get("hello") %>  
  46.      
  47.    _________________________________________________________<br/>  
  48.      
  49.    Person1:address:<s:property value="list[0].address"/><br/>  
  50.    person2:age:<s:property value="list[1].age"/><br/>  
  51.    Person1:cat1:name:<s:property value="list[0].cat.name"/><br/>  
  52.    person1:size:<s:property value="list.size"/><br/>  
  53.    isEmpty:<s:property value="list.isEmpty()"/><br/>  
  54.    _________________________________________________________<br/>  
  55.      
  56.    Person1:address:<%= ((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(0).getAddress() %><br/>  
  57.    person2:age:<%= ((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(1).getAge() %><br/>  
  58.    Person1:cat1:name:<%= ((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(0).getCat().getName() %><br/>  
  59.      
  60.    _________________________________________________________<br/>  
  61.      
  62.    person2:friends:<s:property value="list[1].friends[2]"/><br/>  
  63.    person2:friends:<%= ((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(1).getFriends()[2] %><br/>  
  64.      
  65.    _________________________________________________________<br/>  
  66.      
  67.    person2:map2:<s:property value="list[1].map['hello2']"/><br/>  
  68.    _________________________________________________________<br/>  
  69.      
  70.    filtering:<s:property value="list.{? #this.name.length() > 2}[0].name"/><br/>  
  71.    _________________________________________________________<br/>  
  72.    <s:iterator value="list.{? #this.name.length() > 2}">  
  73.      
  74.    <s:property value="name"/><br/>  
  75.    <s:property value="cat.color"/><br/>  
  76.    <s:property value="friends[0]"/><br/>  
  77.      
  78.    </s:iterator>  
  79.      
  80.    _________________________________________________________<br/>  
  81.      
  82.    projection:<br/>  
  83.    <s:iterator value="list.{age}">  
  84.      
  85.    <s:property/><br/>  
  86.      
  87.    </s:iterator>  
  88.   </body>  
  89. </html>  


相应用到的Person类和Cat类

  1. import java.util.Map;  
  2.   
  3. public class Person  
  4. {  
  5.     private String name;  
  6.       
  7.     private int age;  
  8.       
  9.     private String address;  
  10.       
  11.     private String[] friends;  
  12.       
  13.     private Cat cat;  
  14.       
  15.     private Map<String,String> map;  
  16.       
  17.     public Person(String name,int age,String address,String[] friends,Cat cat,Map<String,String> map)  
  18.     {  
  19.         this.name = name;  
  20.         this.age = age;  
  21.         this.address = address;  
  22.         this.friends = friends;  
  23.         this.cat = cat;  
  24.         this.map = map;  
  25.     }  
  26.       
  27.     public Person()  
  28.     {  
  29.           
  30.     }  
  31.   
  32.     public String getName()  
  33.     {  
  34.         return name;  
  35.     }  
  36.   
  37.     public void setName(String name)  
  38.     {  
  39.         this.name = name;  
  40.     }  
  41.   
  42.     public int getAge()  
  43.     {  
  44.         return age;  
  45.     }  
  46.   
  47.     public void setAge(int age)  
  48.     {  
  49.         this.age = age;  
  50.     }  
  51.   
  52.     public String getAddress()  
  53.     {  
  54.         return address;  
  55.     }  
  56.   
  57.     public void setAddress(String address)  
  58.     {  
  59.         this.address = address;  
  60.     }  
  61.   
  62.     public String[] getFriends()  
  63.     {  
  64.         return friends;  
  65.     }  
  66.   
  67.     public void setFriends(String[] friends)  
  68.     {  
  69.         this.friends = friends;  
  70.     }  
  71.   
  72.     public Cat getCat()  
  73.     {  
  74.         return cat;  
  75.     }  
  76.   
  77.     public void setCat(Cat cat)  
  78.     {  
  79.         this.cat = cat;  
  80.     }  
  81.   
  82.     public Map<String, String> getMap()  
  83.     {  
  84.         return map;  
  85.     }  
  86.   
  87.     public void setMap(Map<String, String> map)  
  88.     {  
  89.         this.map = map;  
  90.     }  
  91.       
  92.       
  93. }  


 

  1. public class Cat  
  2. {  
  3.     private String name;  
  4.       
  5.     private int age;  
  6.       
  7.     private String color;  
  8.       
  9.     public Cat(String name,int age,String color)  
  10.     {  
  11.         this.name = name;  
  12.         this.age = age;  
  13.         this.color = color;  
  14.     }  
  15.       
  16.     public Cat()  
  17.     {  
  18.           
  19.     }  
  20.   
  21.     public String getName()  
  22.     {  
  23.         return name;  
  24.     }  
  25.   
  26.     public void setName(String name)  
  27.     {  
  28.         this.name = name;  
  29.     }  
  30.   
  31.     public int getAge()  
  32.     {  
  33.         return age;  
  34.     }  
  35.   
  36.     public void setAge(int age)  
  37.     {  
  38.         this.age = age;  
  39.     }  
  40.   
  41.     public String getColor()  
  42.     {  
  43.         return color;  
  44.     }  
  45.   
  46.     public void setColor(String color)  
  47.     {  
  48.         this.color = color;  
  49.     }  
  50.       
  51.       
  52. }  


struts2标签使用了OGNL表达式,对于:

username:<s:property value="username"/><br/>
password:<s:property value="password"/><br/>
 <s:property value="username" />value值是OGNL表达式,因为没有使用#号,所以是直接从OGNL的根元素中寻找username,因为在struts2中,OGNL的根元素是值栈,即ValueStack,而ValueStack的最顶上元素一定是Action,这里即是OgnlAction,所以页面将显示OgnlAction中的username属性值。password同理。

对于:

username:<s:property value="#parameters.username"/><br/>
password:<s:property value="#parameters.password"/><br/>

这里使用了命名对象parameters,因为parameters不是根元素,所以要使用#parameters来指定搜索的元素,然后使用点加属性名确定最终的属性值,即#parameters.username

对于:

request:<s:property value="#request.hello"/><br/>
session:<s:property value="#session.hello"/><br/>
application:<s:property value="#application.hello"/><br/>

使用了另外三个命名对象:request,session和application,注意的是requestMap等就是对应的request等

对于:

request:<%= ((Map)ActionContext.getContext().get("request")).get("hello") %><br/>
session:<%= ActionContext.getContext().getSession().get("hello") %><br/>
application:<%= ActionContext.getContext().getApplication().get("hello") %><br/>
    
attr:<%= ((Map)ActionContext.getContext().get("attr")).get("hello") %>

这里使用了java来达到struts标签的效果,主要是演示struts标签的实现原理。这是使用了ActionContext类来访问servletAPI,((Map)ActionContext.getContext().get("request"))将获得request对象,是Map类型的

(在Struts2.0中,Action已经与Servlet API完全分离,这使得Struts2.0的Action具有了更加灵活和低耦合的特性,与Struts1.0相比较而言是个巨大的进步。虽然Struts2.0的Action已经与Servlet API完全分离,但我们在实现业务逻辑处理时经常需要访问Servlet中的对象,如Session、Application等。Struts2.0 提供了一个名字为ActionContext的类,在Action中可以通过该类获得Servlet API。  
  ActionContext是一个Action的上下文对象,Action运行期间所用到的数据都保存在ActionContext中(如Session,客户端提交的参数等信息)。  
  在Action中可以通过下面的代码来创建和使用ActionContext类,关于该类的方法介绍如下所示:  
ActionContext ac=ActionContext.getContext();  

对于:


   Person1:address:<s:property value="list[0].address"/><br/>
   person2:age:<s:property value="list[1].age"/><br/>
   Person1:cat1:name:<s:property value="list[0].cat.name"/><br/>
   person1:size:<s:property value="list.size"/><br/>
   isEmpty:<s:property value="list.isEmpty()"/><br/>
   _________________________________________________________<br/>
  
   Person1:address:<%= ((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(0).getAddress() %><br/>
   person2:age:<%= ((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(1).getAge() %><br/>
   Person1:cat1:name:<%= ((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(0).getCat().getName() %><br/>

这是对列表使用的演示,上半部分使用标签OGNL表达式,下面是java实现

对于:

erson2:friends:<s:property value="list[1].friends[2]"/><br/>
   person2:friends:<%= ((OgnlAction)ActionContext.getContext().getValueStack().peek()).getList().get(1).getFriends()[2] %><br/>

是对数组的访问举例

对于:

 person2:map2:<s:property value="list[1].map['hello2']"/><br/>

是对映射的使用

对于:

filtering:<s:property value="list.{? #this.name.length() > 2}[0].name"/><br/>
   _________________________________________________________<br/>
   <s:iterator value="list.{? #this.name.length() > 2}">
  
   <s:property value="name"/><br/>
   <s:property value="cat.color"/><br/>
   <s:property value="friends[0]"/><br/>
  
   </s:iterator>

是OGNL过滤的演示,注意这里使用了iterator迭代标签,在iterator标签内的property,其value应该是迭代对象的属性,如这里的<s:property value="name"/><br/>迭代对象是Person,那么就是person的name,相对应的,如下迭代:

projection:<br/>
   <s:iterator value="list.{age}">
  
   <s:property/><br/>
  
   </s:iterator>
这是OGNL的映射,迭代的是age集合,迭代对象是一个个age,所以<s:property/><br/>的value不用写,如果写成<s:property value=“age”/><br/>就错了,因为迭代对象age没有一个age属性。

5、关于struts2标签库属性值的%与#的关系:

如果标签的属性值是OGNL表达式,那么无需加上%{}
如果标签的属性值是字符串类型,那么在字符串当中凡出现的%{}都会被解析成OGNL表达式,解析完毕后再与其它的字符串进行拼接构造出最后的字符串值
我们可以在所有的属性之上加%{},这样如果该属性值是OGNL表达式,那么标签处理类就会将%{}忽略掉。

如:

<s:a href="getsinglePerson.action?id=%{#person.id}"><s:property value="username" /></s:a>

如果这里不加上%{},那么#person.id就直接解释成单纯的字符串了,起不到动态赋值的作用

6、如果一个Action执行时间很长,前端页面显示是空白的,这时可以使用一个等待页面,这时要用到一个拦截器:ExcuteAndWaitInterceptor

如果配置了ExcuteAndWaitInterceptor拦截器,在执行Action时,服务器后台会另起一个线程,定期的监控这个Action是否执行完毕,如果没有执行完毕,就显示一个等待页面

 配置Action拦截器:

  1. <action name="OgnlAction" class="com.cdtax.action.ognl.OgnlAction">  
  2.             <interceptor-ref name="defaultStack"></interceptor-ref>  
  3.             <interceptor-ref name="execAndWait"></interceptor-ref>  
  4.             <result name="success">ognl.jsp</result>  
  5.             <result name="wait">/wait.jsp</result>  
  6.         </action>  


然后新建一个等待jsp:

  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%@ taglib prefix="s" uri="/struts-tags" %>  
  3. <%  
  4. String path = request.getContextPath();  
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  6. %>  
  7.   
  8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  9. <html>  
  10.   <head>  
  11.     <base href="<%=basePath%>">  
  12.       
  13.     <title>My JSP 'wait.jsp' starting page</title>  
  14.     <span style="color:#ff0000;"><meta http-equiv="refresh" content="5;url=<s:url includeParams="all" />"/>  
  15. </span>      
  16.     <meta http-equiv="pragma" content="no-cache">  
  17.     <meta http-equiv="cache-control" content="no-cache">  
  18.     <meta http-equiv="expires" content="0">      
  19.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  20.     <meta http-equiv="description" content="This is my page">  
  21.     <!-- 
  22.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  23.     -->  
  24.   
  25.   </head>  
  26.     
  27.   <body>  
  28.     等待界面<span style="color:#ff0000;">,<a href="<s:url includeParams="all" />">Click </a></span> if this page does not reload automatically <br>  
  29.   </body>  
  30. </html>  


注意红色的代码行,是等待页面的关键,每5秒钟自动刷新一次。

修改OgnlAction的excute方法,增加一个睡眠时间,模拟长时间操作:

  1. public String execute() throws Exception  
  2.     {  
  3.         <span style="color:#ff0000;">Thread.sleep(20000);  
  4. </span>       
  5.         // <span style="color:#3333ff;">requestMap.put("hello", "world");  
  6. </span>     sessionMap.put("hello", "hello");  
  7.         applicationMap.put("hello", "world");  
  8.           
  9.         Cat cat1 = new Cat("cat1",20,"red");  
  10.         Cat cat2 = new Cat("Cat2",21,"yellow");  
  11.           
  12.         String[] friends1 = {"test1","test2","test3"};  
  13.         String[] friends2 = {"welcome1","welcome2","welcome3"};  
  14.           
  15.         Map<String,String> map1 = new HashMap<String,String>();  
  16.         Map<String,String> map2 = new HashMap<String,String>();  
  17.           
  18.         map1.put("test1", "test1");  
  19.         map1.put("test2", "test2");  
  20.           
  21.         map2.put("hello1", "hello1");  
  22.         map2.put("hello2", "hello2");  
  23.           
  24.         Person person1 = new Person("zhangsan",20,"beijing",friends1,cat1,map1);  
  25.         Person person2 = new Person("lisi",22,"shanghai",friends2,cat2,map2);  
  26.           
  27.         list = new ArrayList();  
  28.           
  29.         list.add(person1);  
  30.         list.add(person2);  
  31.           
  32.         return SUCCESS;  
  33.     }  


 

注意,requestMap.put("hello", "world"); 这一行要注释掉,否则会出现空指针异常

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多