AngularJS Ajax请求与Spring MVC登录超时解决方案

解决方案:对Angular Ajax的每次请求进行拦截,在请求头增加X-Requested-With标识,后台进行Fiter过滤时,根据X-Requested-With值来判断是否为Ajax请求,如果Session失效且为Ajax请求,则response返回错误编码。Angular拦截的responseError方法中判断是否为Session失效的错误编码,是在js代码中处理Session失效的逻辑操作,比如弹出提示框,跳转至登录界面。

拦截器前台请求

Angular中采用$httpProvider.interceptors拦截方式来做处理Ajax请求,拦截Ajax请求的request、response、responseError错误码状态

  1. 在AngularJS所有request请求头(Ajax请求)中都加上 X-Requested-With
  2. 处理responseError方法的Status状态码,判断是否和Filter中response定义的Code一致,符合条件则跳转至登录界面
app.config(['$logProvider', '$httpProvider','$stateProvider','$urlRouterProvider', function($logProvider, $httpProvider,$stateProvider,$urlRouterProvider){
        $logProvider.debugEnabled(true);
        $urlRouterProvider.otherwise("/home");

        $httpProvider.interceptors.push(['$rootScope', '$q', '$location', '$timeout',
          function ($rootScope, $q, $location, $timeout) {
             return {
                 'request': function (config) {
                     config.headers['X-Requested-With'] = 'XMLHttpRequest';
                     return config || $q.when(config);
                 },
                 'requestError': function (rejection) {
                     return rejection;
                 },
                 'response': function (response) {
                     return response || $q.when(response);
                 },
                 'responseError': function (response) {
                     console.log('responseError:' + response);
                     if (response.status === 401 || response.status === 403) {
                         $timeout(function () { 
                             window.location = "/login"; 
                             //也可弹出对话框提示
                         }, 3000);
                         return false;
                     }
                     else if (response.status === 500) {
                         $location.path('/500.html');
                         return false;
                     }
                     return $q.reject(response);
                 }
             };
         }]);
     }

Fiter过滤

主要逻辑:

  1. 获取逻辑头String requestType = request.getHeader(“X-Requested-With”);
  2. 判断是否Angular请求,如果是则返回401错误码,该标识可自定义
public class SessionInterceptor implements HandlerInterceptor {
    public SessionInterceptor() {
        // TODO Auto-generated constructor stub
    }

    private String mappingURL;    // 利用正则映射到不需要拦截的路径 ,如代码、常用资源信息等
    private String[] excludeUrls; // 不需要拦截的路径,如登录、退出等

    public void setExcludeUrls(String[] excludeUrls) {
        this.excludeUrls = excludeUrls;
    }

    public void setMappingURL(String mappingURL) {
        this.mappingURL = mappingURL;
    }

    /**
     * 在业务处理器处理请求之前被调用 如果返回false 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
     * 
     * 如果返回true 执行下一个拦截器,直到所有的拦截器都执行完毕 再执行被拦截的Controller 然后进入拦截器链,
     * 从最后一个拦截器往回执行所有的postHandle() 接着再从最后一个拦截器往回执行所有的afterCompletion()
     */
    @SuppressWarnings("unchecked")
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
                    String uri = getURI(request);
        String rooturi = getRootURI(request);
        RequestThreadLocal.setRequestThreadLocal(request);
//      // 不在验证的范围内
        if (exclude(uri)) {
            return true;
        }
        // 用户为null跳转到登陆页面
        YSysUser user = (YSysUser) request.getSession().getAttribute(SystemConstants.SESSION_USER);
        if (user == null) {
            String requestType = request.getHeader("X-Requested-With");  
            if (!StringUtils.isEmpty(requestType) && requestType.equalsIgnoreCase("XMLHttpRequest")) {  
                response.setHeader("sessionstatus", "timeout");  
                response.sendError(401, "session timeout.");  
                return false;
            }else{
                response.sendRedirect(rooturi + "/login");
                return false;
            }
        }
        //验证URL权限
    }

    // 在业务处理器处理请求执行完成后,生成视图之前执行的动作
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        // log.info("==============执行顺序: 2、postHandle================");
    }

    /**
     * 在DispatcherServlet完全处理完请求后被调用
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        // log.info("==============执行顺序: 3、afterCompletion============");
    }
}

参考资料:http://blog.csdn.net/zhyh1986/article/details/8695777

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值