在开发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一个消息队列。