shiro+layui登录超时后发起ajax异步请求,跳到登录界面

一、后端配置:
1、创建LoginFilter.java(过滤器主程序)
注意:有用Shiro权限框架的继承AdviceFilter类,重写preHandle()方法,没有的请直接实现Filter接口,重写doFilter()方法

package com.seesun2012.web.mall.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.web.servlet.AdviceFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.seesun2012.web.mall.security.ShiroUtils;

/**
 * 
 *           ┏┓    ┏┓+ +
 *        ┏┛┻━━━┛┻┓ + +
 *        ┃       ┃
 *        ┃   ━   ┃ ++ + + +
 *        ████━████ ┃+
 *        ┃       ┃ +
 *        ┃   ┻   ┃
 *        ┃       ┃ + +
 *        ┗━┓   ┏━┛
 *          ┃   ┃
 *          ┃   ┃ + + + +
 *          ┃   ┃					God beast body, code no BUG
 *          ┃   ┃ +				神兽护体,代码无BUG
 *          ┃   ┃
 *          ┃   ┃  +
 *          ┃    ┗━━━┓ + +
 *          ┃        ┣┓
 *          ┃        ┏┛
 *          ┗┓┓┏━┳┓┏┛ + + + +
 *           ┃┫┫ ┃┫┫
 *           ┗┻┛ ┗┻┛+ + + +
 *
 * @title:		电商-Ajax请求过滤器(未登录跳转登陆界面)
 * @version		v1.0.0
 * @author		研发中心-seesun2012
 * @date		2019年02月20日  下午14:26:23  周三
 *
 */
public class LoginFilter extends AdviceFilter {
	
	private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class);
	
	private static final String[] filter = {"/login", "/getVCode", "/doLogin", "/system/publickeyhex", ".css", ".js", ".png", ".jng", ".gif", "jpeg", ".otf", "/logout"};
	
	@Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
		HttpServletRequest hsRequest = (HttpServletRequest) request;
		HttpServletResponse hsResponse = (HttpServletResponse) response;
        String url = hsRequest.getRequestURI();
        
        // 不需要过滤的请求地址以及文件
		for (String str : filter) {
			if (url.lastIndexOf(str) >= 0){
				return true;
			}
		}
		
 		// === 复制粘贴请修改此处 === :从缓存中获取用户登陆信息(可以是Redis、Session、Memcached、MySQL查询)
		Object sysUser = ShiroUtils.getUserEntity();
		// 如果没有获取到用户信息,将退出到登陆界面
        if (null == sysUser) {
        	// 从请求头部获取请求方式
            String requestedWith = hsRequest.getHeader("X-Requested-With");
            // 如果是Ajax返回指定数据
            if (StringUtils.isNotEmpty(requestedWith) && StringUtils.equals(requestedWith, "XMLHttpRequest")) {
				// 将要重定向WEB地址(项目地址)
                String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + hsRequest.getContextPath() + "/";
                hsResponse.setHeader("sessionstatus", "TIMEOUT");					// 返回特定数据(头部信息)
                hsResponse.setHeader("content_path", basePath + "login");			// 返回特定数据(首页登陆地址)
                hsResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);				// 403 禁止:状态代码(403),指示服务器了解请求,但拒绝履行。
                return false;
            } else {	// 不是Ajax进行重定向处理
                logger.info( url + "重定向到了登录界面");
                hsResponse.sendRedirect(hsRequest.getContextPath() + "/login");		// 重定向到登陆界面
                return false;
            }
        }
        return true;
	 }	
}

2、spring-shiro.xml中配置过滤器信息(有删减,对照修改):


<beans>
	
	<bean id="loginFilter" class="com.seesun2012.web.mall.filter.LoginFilter">bean>

	
    <bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
        <property name="redirectUrl" value="/login" />
    bean>

	
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
	
		//部分省略...

	    
	    <property name="filters">
            <map>
            	
                <entry key="authc" value-ref="loginFilter" />
                
                <entry key="logout" value-ref="logoutFilter" />
            map>
        property>
	
	    //部分省略...
	
	bean>
beans>

3、定义公共js文件,在Common.js中重写Ajax.ajaxSetup()方法:

if(typeof jQuery != 'undefined') {
	 //重写ajax
	$.ajaxSetup( {
	    //设置ajax请求结束后的执行动作
	    complete :
	        function(XMLHttpRequest, textStatus) {
	            // 通过XMLHttpRequest取得响应头,sessionstatus
	    		var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus");
	    		if (sessionstatus == "TIMEOUT") {
	    			var win = window;
	    			while (win != win.top) {
	                    win = win.top;
	                }
	                win.location.href = XMLHttpRequest.getResponseHeader("content_path");
	            }
	        }
	});
}

// 如果使用了layui框架,也必须要重写layui的ajax(用什么框架自行查找对应解决方案)
if(typeof layui != 'undefined') {
	layui.use(['form','laydate'],function(){
		var form = layui.form,
			laydate = layui.laydate,//日期
			$ = layui.jquery;
		 $(".layui-date").each(function(){
		 	var id = $(this).attr("id");
		 	laydate.render({
		 		elem:'#'+id,
		 		format:'yyyy/MM/dd',
		 		max:0
		 	});
		 });
		 //重写ajax(layui)
		 $.ajaxSetup({
			//设置ajax请求结束后的执行动作
		    complete :
		        function(XMLHttpRequest, textStatus) {
		            // 通过XMLHttpRequest取得响应头,sessionstatus
		    		var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus");
		    		if (sessionstatus == "TIMEOUT") {
		    			var win = window;
		    			while (win != win.top) {
		                    win = win.top;
		                }
		                win.location.href = XMLHttpRequest.getResponseHeader("content_path");
		            }
		        }
		});
	});
}

4、在调用ajax的文件中引入3中的js文件Common.js:

<html>
	<head>
		<script type="text/javascript" src="js/common/js" charset="utf-8">script>
	head>
	<body>
		内容省略...
	body>
html>




参考文献:https://blog.csdn.net/wahaha13168/article/details/82390017


























注:以上内容仅提供参考和交流,请勿用于商业用途,如有侵权联系本人删除!


持续更新中…

如有对思路不清晰或有更好的解决思路,欢迎与本人交流,QQ群:273557553,个人微信:
你遇到的问题是小编创作灵感的来源!


你可能感兴趣的:(Java)