好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

解决Shiro 处理ajax请求拦截登录超时的问题

Shiro 处理ajax请求拦截登录超时

配置全局ajax配置

?

1

2

3

4

5

6

7

8

9

10

11

$.ajaxSetup({

     complete: function (XMLHttpRequest,textStatus){

           if (textStatus== "parsererror" ){

                $.messager.alert( '提示信息' , "登陆超时!请重新登陆!" , 'info' , function (){

                    window.location.href = 'login.jsp' ;

                });

           } else if (textStatus== "error" ){

               $.messager.alert( '提示信息' , "请求超时!请稍后再试!" , 'info' );

           }

     }

});

在js里面配置全局的ajax配置即可!

Shiro session超时页面跳转的处理

问题描述

shiro在管理session后,在session超时会进行跳转,这里有两种情况需要考虑,一种是ajax方式的请求超时,一种页面跳转请求的超时。

本文从这两个方面分别考虑并处理。

ajax请求超时处理

思路:通过Filter后判定,当前是否session超时,超时判定是否是ajax请求,如果是ajax请求,则在response头部设置session-status值,返回到前端读取到相应值后进行处理

后端Filter代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

package com.cnpc.framework.filter;

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.session.Session;

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

/**

  * * filter过滤器,获取项目路径,设置ajax超时标识

  * @author billJiang QQ:475572229

  */

public class SystemFilter implements Filter {

     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException,

             ServletException {

         HttpServletRequest request = (HttpServletRequest) servletRequest;

         HttpServletResponse response = (HttpServletResponse) servletResponse;

         System.out.println(request.getRequestURL());

         String basePath = request.getContextPath();

         request.setAttribute( "basePath" , basePath);

         if (!SecurityUtils.getSubject().isAuthenticated()) {

             //判断session里是否有用户信息

             if (request.getHeader( "x-requested-with" ) != null

                     && request.getHeader( "x-requested-with" ).equalsIgnoreCase( "XMLHttpRequest" )) {

                 //如果是ajax请求响应头会有,x-requested-with

                 response.setHeader( "session-status" , "timeout" ); //在响应头设置session状态

                 return ;

             }

         }

         filterChain.doFilter(request, servletResponse);

     }

     @Override

     public void destroy() {

         // TODO Auto-generated method stub

     }

     @Override

     public void init(FilterConfig arg0) throws ServletException {

         // TODO Auto-generated method stub

     }

}

前端通用ajax处理

注意session-status上下文部分

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

function ajaxPost(url, params, callback) {

     var result = null ;

     var headers={};

     headers[ 'CSRFToken' ]=$( "#csrftoken" ).val();

     $.ajax({

         type : 'post' ,

         async : false ,

         url : url,

         data : params,

         dataType : 'json' ,

         headers:headers,

         success : function (data, status) {

             result = data;

             if (data&&data.code&&data.code== '101' ){

                 modals.error( "操作失败,请刷新重试,具体错误:" +data.message);

                 return false ;

             }

             if (callback) {

                 callback.call( this , data, status);

             }

         },

         error : function (err, err1, err2) {

             console.log( "ajaxPost发生异常,请仔细检查请求url是否正确,如下面错误信息中出现success,则表示csrftoken更新,请忽略" );

             console.log(err.responseText);

             if (err && err.readyState && err.readyState == '4' ){

                 var sessionstatus=err.getResponseHeader( "session-status" );

                 if (sessionstatus== "timeout" ){

                     //如果超时就处理 ,指定要跳转的页面

                     window.location.href=basePath+ "/" ;

                 }

                 else { //csrf异常

                     var responseBody = err.responseText;

                     if (responseBody) {

                         responseBody = "{'retData':" + responseBody;

                         var resJson = eval( '(' + responseBody + ')' );

                         $( "#csrftoken" ).val(resJson.csrf.CSRFToken);

                         this .success(resJson.retData, 200);

                     }

                     return ;

                 }

             }          

             modals.error({

                 text : JSON.stringify(err) + '<br/>err1:' + JSON.stringify(err1) + '<br/>err2:' + JSON.stringify(err2),

                 large : true

             });

         }

     });

     return result;

}

非ajax请求超时跳转

在本试验中,使用jquery.load方式进行了页面加载,并重载jquery.fn.load改写了该方法,通过beforeSend去除了ajax标识,由于超时返回的登录页面可能嵌入当前页面,所以需要判断当前获得的页面是否是登录页面,如果是登陆页面,则再经过一次跳转到登陆页(或者首页)。

重载的jquery.fn.load方法如下,注意beforeSend和responseText.startWith部分内容。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

var _old_load = jQuery.fn.load;

jQuery.fn.load = function ( url, params, callback ) {

     //update for HANZO, 2016/12/22

     if ( typeof url !== "string" && _old_load) {

         return _old_load.apply( this , arguments );

     }

     var selector, type, response,

         self = this ,

         off = url.indexOf( " " );

     if ( off > -1 ) {

         selector = jQuery.trim( url.slice( off ) );

         url = url.slice( 0, off );

     }

     if ( jQuery.isFunction( params ) ) {

         callback = params;

         params = undefined;

     } else if ( params && typeof params === "object" ) {

         type = "POST" ;

     }

     if ( self.length > 0 ) {

         jQuery.ajax( {

             url: url,

             beforeSend: function ( xhr ) { 

                     xhr.setRequestHeader( 'X-Requested-With' , {toString: function (){ return '' ; }}); 

             }, 

             type: type || "GET" ,

             dataType: "html" ,

             data: params

         } ).done( function ( responseText ) {

             //console.log(responseText);

             response = arguments;

             //页面超时跳转到首页

             if (responseText.startWith( "<!--login_page_identity-->" )){

                 window.location.href=basePath+ "/" ;

             } else {

                 self.html(selector ?

                     jQuery( "<div>" ).append(jQuery.parseHTML( responseText )).find(selector) :

                     responseText);

             }

         } ).always( callback && function ( jqXHR, status ) {

             self.each( function () {

                 callback.apply( this , response || [ jqXHR.responseText, status, jqXHR ] );

             } );

         } );

     }

     return this ;

};

可通过设置session的timeout来测试结果。需要注意的是ajax请求要使用ajaxPost方法,该方法统一处理了超时跳转。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/qq_25223941/article/details/51732667

查看更多关于解决Shiro 处理ajax请求拦截登录超时的问题的详细内容...

  阅读:27次