【struts2】值棧(后篇)


  在值棧(前篇)我們學習了值棧的基本知識,接下來,來看看在程序中具體如何使用值棧。

  ActionContext的基本使用

  1.1 如何獲取?

  要獲取ActionContext有兩個基本的方法,如果在不能獲取到ActionInvocation的地方,可以直接使用ActionContext一個靜態的getContext方法,就可以訪問到當前的ActionContext了,示例如下:

ActionContext ctx = ActionContext.getContext();  

  如果在能獲取到ActionInvocation的地方,比如在攔截器里面、自定義的Result里面等,可以通過ActionInvocation來獲取到ActionContext,示例如下:

ActionContext ctx = actionInvocation.getInvocationContext();  

  1.2 獲取過后,如何使用?

   ActionContext主要的功能是用來存放數據的,典型的方法如下:

  • get(String key):根據key從ActionContext當前的存儲空間里面獲取相應的值
  • put(String key, Object value):把值存儲在ActionContext的存儲空間里面
  • Map<String,Object> getApplication():返回ServletContext中存儲的值
  • Map<String,Object> getSession():返回HttpSession中存儲的值
  • Map<String,Object> getContextMap():返回當前context存儲的值
  • Map<String,Object> getParameters():返回HttpServletRequest對象里面存儲的,客戶端提交的參數
  • ValueStack getValueStack():獲取OGNL的值棧

  對於getXXX的方法,都有對應的setXXX方法,這里就不去贅述了,具體的請參看Struts2的API文檔。

  1.3 應用示例

  在《自定義更強大的logger攔截器》《自定義登陸驗證攔截器》中,兩個攔截器都使用了ActionContext對象,詳細請查看這兩篇文章。

  2 ValueStack的基本使用

  在值棧(前篇)中,我們看到了ValueStack被包含在ActionContext中,ValueStack也是用來存儲對象的,但是它主要是通過OGNL表達式來訪問,也就是說,在Struts2里面主要是通過標簽來訪問的。ValueStack有一個特點,如果訪問的值棧里有多個對象,且相同的屬性在多個對象中同時出現,則值棧會按照從棧頂到棧底的順序,尋找第一個匹配的對象。

  2.1 如何獲取?

  直接由ActionContext對象的getValueStack()方法即可獲取

  2.2 如何使用?

  ValueStack主要的功能也是用來存放數據的,典型的方法如下:

  • Object findValue(String expr):根據表達式在value stack中,按照缺省的訪問順序去獲取表達式對應的值
  • void setValue(String expr, Object value):根據表達式,按照缺省的訪問順序,向value stack中設置值
  • Object peek():獲取value stack中的頂層對象,不修改value stack對象
  • Object pop():獲取value stack中的頂層對象,並把這個對象從value stack中移走
  • void push(Object o):把對象加入到value stack對象中,並設置成為頂層對象

  2.3 應用示例

  前面的示例中,歡迎頁面顯示的帳號,是從登錄頁面填寫並傳遞到后台的數據,假如現在想要修改在歡迎頁面顯示的帳號數據,但是前面從登錄頁面填寫並傳遞到后台的數據不需要變化,那么該怎么實現呢?先來分析一下,要想修改result頁面顯示的值,肯定需要在Result處理之前修改這個值,否則等Result處理完成過后再改就沒有意義了。因此,可以選用PreResultListener的技術,在里面把值修改好,然后再進行Result處理。另外一點,在歡迎頁面是通過標簽來獲取帳號的數據並展示的,也就是說值的來源是value stack,因此,在PreResultListener里面要修改的就是value stack里面的值。好了,清楚該干什么過后,來具體看看示例。

  1)先來實現PreResultListener,在里面修改value stack里面的值,示例如下:

public class MyPreResult implements PreResultListener{  
    public void beforeResult(ActionInvocation actionInvocation, String result) {  
        System.out.println("現在處理Result執行前的功能,result="+result);  
        actionInvocation.getInvocationContext().getValueStack().setValue("account", "被修改了");  
    }  
}  

  2)實現了PreResultListener,還需要在運行之前注冊,這里選擇在Action里面來注冊這個監聽器,示例如下:

public class HelloWorldAction extends ActionSupport {  
    private String account;  
    private String password;  
    private String submitFlag;  
    public String execute() throws Exception {  
        this.businessExecute();  
        ActionContext c = ActionContext.getContext();  
        MyPreResult pr = new MyPreResult();  
        c.getActionInvocation().addPreResultListener(pr);  
        return "toWelcome";  
    }  
    /** 
     * 示例方法,表示可以執行業務邏輯處理的方法, 
     */  
    public void businessExecute(){  
        System.out.println("用戶輸入的參數為==="+"account="+account+",password="+password+",submitFlag="+submitFlag);  
    }  
    //屬性對應的getter/setter方法,省略了  
}  

  3)struts.xml、登陸界面和歡迎界面都不變。歡迎界面中的<s:property value="account"/>就可以獲得MyPreResult類中修改的account值了。

  由於通常情況下,向value stack里面壓入值都是由Struts2去完成,而訪問value stack多是通過標簽中的OGNL表達式,因而直接使用ValueStack的機會並不是很多。

  參考資料:http://www.iteye.com/topic/1124526

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM