zoukankan      html  css  js  c++  java
  • sturts2架构,后台向前端传递消息应该怎么设计?

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

  • 相关阅读:
    有趣的面试题 11 单向链表
    CLR via C# 读书笔记 13 前台线程和后台线程
    c# 使用 new 操作符构造新对象中做了一些什么 (简单版)
    CLR via C# 读书笔记 11 何时使用线程或者线程池
    CLR via C# 读书笔记 31 一种单实例应用程序的实现(信号量)
    延时加载lazyload
    [评论]为什么中国的程序员技术偏低
    关于陈列设计和一些细节的体验
    滚动
    JavaScript 的 parseInt 取整
  • 原文地址:https://www.cnblogs.com/cha1r/p/3524435.html
Copyright © 2011-2022 走看看