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

来源:互联网 发布:印度制造业数据 编辑:程序博客网 时间:2024/05/17 16:54

解决方案:对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
原创粉丝点击