sturts2架构,后台向前端传递消息应该怎么设计?
2014-01-17 17:44 _cha1R 阅读(256) 评论(0) 编辑 收藏 举报在开发WEB项目时,我们经常需要再后台代码里向前端页面传递消息。例如当用户登陆后,向用户提示登陆成功。
在我们最初学习的时候,我们一般会在action里写上一个message变量,然后提供get set方法。当我们在action 返回result后转发到jsp页面,那样在jsp页面就可以用el表达式或者ognl表达式获取到。
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刷新的时候,我发现浏览器提示我在尝试重复提交表单,是否要重复提交这个表单(即重复登录)。
我顿时就觉得这用户体验太不行,起码目前来说,有哪个网站是首页刷新会提示这个的。。
于是我想到了redirect,在struts.xml里配上:
<result name="index" type="redirect">/index.jsp</result>
重启,重新登陆。一切似乎很顺利,跳到index.jsp,刷新,没提示我重复提交。。
但是我发现“登陆成功”的提示不见了。。原因很显然,我redirect后,在ValueStack里的message变量已经被清空.
那这时候就只能依赖session了。于是我参考了新浪微博的一个设计:每一个账号拥有自己的一个消息队列(猜的)。
我写了一个类,专门用来存取消息的,这个类很简单:
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一个消息队列。