• Extjs springmvc session 超时 处理



    如果你的项目使用ExtJS作为表现层,你会发现,SESSION超时控制将是一个问题。
    本文将就自己的经验,来解决这一问题,当然,解决问题并非只有一种方法,我只是提出我的方法。
    首先,做超时控制,必需使用过滤器,而我们既然使用了Spring MVC,那就用拦截器取代吧,写一个拦截器,用来拦截用户请求,当然,这个拦截器还需要可以配置哪些请求是不需要拦截的。
    [java] view plaincopy
    /**
    *
    */
    package net.bioslink.business.intercepter;

    import java.io.PrintWriter;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import net.bioslink.common.util.ConfigureUtil;
    import net.bioslink.common.vo.Constants;

    import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang.ArrayUtils;
    import org.apache.log4j.Logger;
    import org.springframework.stereotype.Repository;
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

    /**
    * @author leoly
    *
    */
    @Repository
    public class SystemAccessInterceper extends HandlerInterceptorAdapter {
    private final Logger logger = Logger.getLogger(getClass());

    @Override
    public boolean preHandle(HttpServletRequest request,
    HttpServletResponse response, Object handler) throws Exception {
    String uri = request.getRequestURI();
    String[] noFilters = ConfigureUtil.getStringArray("no_filter_setting");
    boolean isFilter = true;
    if (!ArrayUtils.isEmpty(noFilters)) {
    for (String u : noFilters) {
    if (uri.contains(u)) {
    isFilter = false;
    break;
    }
    }
    }

    if (isFilter) {
    // Session
    Object obj = request.getSession()
    .getAttribute(Constants.SESSION_ID);
    if (null == obj) {
    logger.info("登录超时!!");
    PrintWriter writer = response.getWriter();
    writer.print("<script>top.location='http://127.0.0.1:8080/VkDesktop/login/loginSystem.do';</script>SESSION_TIMEOUT_ERROR");
    IOUtils.closeQuietly(writer);
    return false;
    } else {
    request.setAttribute("LOG_ACCESS_TIME",
    System.currentTimeMillis());
    logger.info(obj + "访问了" + uri);
    }
    }
    return super.preHandle(request, response, handler);
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
    HttpServletResponse response, Object handler, Exception ex)
    throws Exception {
    // TODO Auto-generated method stub
    super.afterCompletion(request, response, handler, ex);
    Object obj = request.getAttribute("LOG_ACCESS_TIME");
    if (null != obj) {
    long accessTime = (long) obj;
    logger.info("处理请求" + request.getRequestURI() + "耗时"
    + (System.currentTimeMillis() - accessTime) + "毫秒!");
    }
    }
    }

    然后,将这个拦截器注册到Spring MVC中,在xxx-servlet.xml文件中添加注册代码:
    [html] view plaincopy
    <mvc:interceptors>
    <bean class="net.bioslink.business.intercepter.SystemAccessInterceper" />
    </mvc:interceptors>

    OK,现在这个拦截器已经开始工作了,它会拦截用户请求,判断SESSION中是否存在登录信息,如果不存在,则说明已经超时,拦截器向客户问写一段代码
    [java] view plaincopy
    writer.print("<script>top.location='http://127.0.0.1:8080/VkDesktop/login/loginSystem.do';</script>SESSION_TIMEOUT_ERROR");
    这样,如果客户端是网页,它就会自动跳到登录页面,如果不是网页(如AJAX请求),我们需要在客户端中判断返回的字符串中是否包含“SESSION_TIMEOUT_ERROR”,如果有的话就做出跳到首页的处理。

    那么,现在轮到客户端了,因为使用的是ExtJS,几乎所有的请求都是AJAX请求,所以判断SESSION_TIMEOUT_ERROR是关键。那总不能所有的AJAX请求都加上这些判断吧??OMG,杀了我吧,可怜的码农……
    其实,我们可以写一个TimeoutControl类,封装一些我们需要修改和添加的东西,来实现超时跳转功能!谁叫ExtJS提供了这么多类功能(继承,重写,覆盖)呢?
    我们知道,ExtJS的请求虽然都是AJAX请求,但是却可以区分为Store请求和一般的AJAX请求,那么我们的TimeoutControl类就需要重新构造这些请求方式,并且,以后写的所有请求都需要使用这个类来完成。
    [javascript] view plaincopy
    Ext.define('Ext.ux.TimeoutControl', {
    extend : 'Ext.data.Store',
    alias : 'widget.timeoutstore',
    constructor : function(config) {
    Ext.apply(config.proxy, {
    listeners : {
    exception : function(self, response) {
    var responseText = response.responseText;
    if (responseText
    && responseText.indexOf("SESSION_TIMEOUT_ERROR") > 0) {
    top.location = '../login/loginSystem.do';
    }
    }
    }
    });
    this.callParent([config]);
    },

    statics : {
    request : function(config) {
    var f = config.success;
    config.success = Ext.Function.createInterceptor(f, function(
    response) {
    var txt = response.responseText;
    // alert(txt);
    if (txt && txt.indexOf("SESSION_TIMEOUT_ERROR") > 0) {
    top.location = '../login/loginSystem.do';
    return false;
    }

    return true;
    });
    Ext.Ajax.request(config);
    }
    }
    });


    这个类中,我们继承了Ext.data.Store,并且在构造器中动态加入了一个proxy的exception处理函数,也就是说,只要使用此类,无论Store的proxy中写没写exception函数,都会在这里添加上,而这个函数就是处理超时控制的。然后,这个类还提供了一个静态方法request,这个request方法会调用Ext.Ajax.request(config),但是在调用之前,我们给配置的success函数添加了一段判断超时的代码,使用的是ExtJS的函数拦截方法,效果杠杠的。
    最后,只要我们在使用到Store的地方中使用Ext.ux.TimeoutControl类,在使用Ext.Ajax.request的地方中使用Ext.ux.TimeoutControl.request取代,那么,超时控制就完成了。
    使用Store的例子:
    [javascript] view plaincopy
    var store = Ext.create('Ext.ux.<span style="font-size:18px; white-space: pre; background-color: rgb(240, 240, 240);">TimeoutControl</span>', {
    model : 'MyDesktop.data.WorkOrderModule',
    remoteSort : true,
    remoteFilter : true,
    sorters : [new Ext.util.Sorter({
    property : 'reportId',
    direction : 'ASC'
    })],
    proxy : {
    type : 'ajax',
    actionMethods : {
    read : 'POST'
    },
    extraParams : {
    projectCode : "44190008",
    orderMonth : 2,
    id : 0
    },
    pageParam : 'pageNo',
    limitParam : 'pageSize',
    url : '../lebang/workOrder/queryWorkorderList.do',
    reader : {
    type : 'json',
    root : 'orders',
    totalProperty : 'totalCount'
    }
    }
    });

    使用AJAX请求的例子:
    [javascript] view plaincopy
    Ext.ux.TimeoutControl.request({
    url : "../user/logout.do",
    timeout : 60000,
    method : 'POST',
    disableCaching : false,
    params : {},
    success : function(response) {
    window.location = '../login/loginSystem.do';
    },
    failure : function() {
    Ext.Msg.alert("系统提示", "注销异常,请联系管理人员!!");
    }
    });

  • 相关阅读:
    使用eclipse新建一个SWT工程
    C++类的构造函数
    D3D编程的常见报错及解决
    D3D窗口的初始化
    C++联合体的内存使用
    QT程序如何编译
    Restart
    HTML
    信号、槽位及布局
    QT对话框程序
  • 原文地址:https://www.cnblogs.com/jiqiyoudu/p/4739889.html
Copyright © 2020-2023  润新知