在開發WEB項目時,咱們常常須要再後臺代碼裏向前端頁面傳遞消息。例如當用戶登錄後,向用戶提示登錄成功。前端
在咱們最初學習的時候,咱們通常會在action裏寫上一個message變量,而後提供get set方法。當咱們在action 返回result後轉發到jsp頁面,那樣在jsp頁面就能夠用el表達式或者ognl表達式獲取到。java
public class UserAction { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String execute()throws Exception { return SUCCESS; }
}
後來我發現這種方式不太好。瀏覽器
首先,咱們填寫完帳戶和密碼的時候,跳轉到action,而後action跳轉到index.jsp,index.jsp是主頁,可是提示登陸成功。看起來一切都很好,可是當我習慣性的按了下F5刷新的時候,我發現瀏覽器提示我在嘗試重複提交表單,是否要重複提交這個表單(即重複登陸)。session
我頓時就以爲這用戶體驗太不行,起碼目前來講,有哪一個網站是首頁刷新會提示這個的。。jsp
因而我想到了redirect,在struts.xml裏配上:學習
<result name="index" type="redirect">/index.jsp</result>
重啓,從新登錄。一切彷佛很順利,跳到index.jsp,刷新,沒提示我重複提交。。網站
可是我發現「登錄成功」的提示不見了。。緣由很顯然,我redirect後,在ValueStack裏的message變量已經被清空.this
那這時候就只能依賴session了。因而我參考了新浪微博的一個設計:每個帳號擁有本身的一個消息隊列(猜的)。spa
我寫了一個類,專門用來存取消息的,這個類很簡單:設計
package cn.tanjiay.mbt.pojo; import java.util.LinkedList; /** * 消息隊列,該對象會放在Session中,以先進先出的方式。 * 每次獲取後會清除該消息 * @author _cha1R * @data 2014-1-17 */ public class MessageQueue { LinkedList<String> messageList = new LinkedList<String>(); public void putMessage(String message){ messageList.addLast(message); } public String getMessage(){ return messageList.pollFirst(); } }
這個類型依賴了LinkedList類,可是我爲何不直接用LinkList呢?很簡單的緣由。我在jsp頁面用了el表達式。
在我寫${message}的時候,el會找到getMessage()方法,調用它而後返回值顯示子頁面上。因此我順便改了一下getMessage()方法和setMessage()方法:
/** * 獲取一個消息 * @return */ public String getMessage() { MessageQueue mq = getFromSession("messageQueue"); if(mq == null){ return null; } return mq.getMessage(); } /** * 向session消息隊裏推送一個消息 * @param message */ public void setMessage(String message) { MessageQueue mq = getFromSession("messageQueue"); if(mq == null){ mq = new MessageQueue(); put2Session("messageQueue", mq); } mq.putMessage(message); }
setMessage()方法每次都會斷定session裏有沒有消息隊列,若是沒有就創一個丟進session。而後往session裏的消息隊列存放消息。
當調用getMessage()的時候,就能夠拿到存放的消息。並且只能拿一次。
這樣就實現了一個session一個消息隊列。