二、思路
1、分析原因
由于session失效问题,导致shiro会路径指向登陆页面,因为用了jquery的load()所以页面就被嵌入到了父图层中
2、解决
事后处理(js),事前处理(拦截器)
三、解决
1、前端 + 后端
后端:监控sesson是否失效,失效了,再判断是否是ajax请求,如果是则设置一个timeout的状态。告诉前端。
public class SessionFilter implements Filter { @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
// if (httpServletRequest.getSession().getAttribute("user") == null) {
if (!SecurityUtils.getSubject().isAuthenticated()) {
//判断session里是否有用户信息
if (httpServletRequest.getHeader("x-requested-with") != null
&& httpServletRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
//如果是ajax请求响应头会有,x-requested-with
httpServletResponse.setHeader("sessionstatus", "timeout");//在响应头设置session状态
return;
} }
chain.doFilter(request, response); } @Override
public void destroy() { } }
前端:由于用到了load() (其实也是ajax请求),所以可以用ajax全局设置解决,
$.ajaxSetup({ complete:function(XMLHttpRequest,textStatus){
//通过XMLHttpRequest取得响应头,sessionstatus,
var sessionstatus=XMLHttpRequest.getResponseHeader("sessionstatus");
if(sessionstatus=="timeout"){
//如果超时就处理 ,指定要跳转的页面
window.location = "/loginUI";
}
}
});
还有一种是纯前端也是 $.ajaxSetup这个,但是忘记地址了,也没验证。好像是oschina的一篇文章。
2、纯后端
也是受到上面的启发,在后端的时候既然知道了session有问题,就可以直接在后端写js了。省去前端问题。
import java.io.IOException;import java.io.PrintWriter;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.ack.bmt.auth.util.ShiroUtil;public class SessionFilter implements Filter { @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
String uri = httpServletRequest.getRequestURI();
boolean b = uri.indexOf("ajaxLogin") >= 0; //ajax 登陆 排除
if (!ShiroUtil.hasAuthenticated() && !b) {
// 判断session里是否有用户信息
if (httpServletRequest.getHeader("x-requested-with") != null
&& httpServletRequest.getHeader("x-requested-with")
.equalsIgnoreCase("XMLHttpRequest")) {
// 如果是ajax请求响应头会有,x-requested-with
//httpServletResponse.setHeader("sessionstatus", "timeout");// 在响应头设置session状态
redirect(httpServletRequest, httpServletResponse);
return;
} } chain.doFilter(request, response);
} @Override
public void destroy() { } void redirect(HttpServletRequest request, HttpServletResponse response) {
response.setHeader("sessionstatus", "timeout");// 在响应头设置session状态
response.setContentType("text/html");
PrintWriter out;
try {
out = response.getWriter();
out.print("window.location = \"/loginUI\";");
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
四、总结