场景
一般javaweb网站都有用户登录,而有一些操作必须用户登录才能进行,常见流程:用户请求--》后台判断是否登录--》没登录跳转到登录界面,登录用户正常操作
解决思路
在用过滤器过滤请求,判断是否登录,如果未登录,返回参数跳转的登录界面,登录了的请求放行
具体实现
- 新建一个web工,参考:【Maven】Eclipse 使用Maven创建Java Web项目
- 新建一个LoginFilter过滤器类,继承Filter类
1 package com.test.login; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.util.ArrayList; 6 import java.util.List; 7 8 import javax.servlet.Filter; 9 import javax.servlet.FilterChain; 10 import javax.servlet.FilterConfig; 11 import javax.servlet.ServletException; 12 import javax.servlet.ServletRequest; 13 import javax.servlet.ServletResponse; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 import javax.servlet.http.HttpSession; 17 18 public class LoginFilter implements Filter { 19 20 public static List<String> pattenURL = new ArrayList<String>(); 21 22 @Override 23 public void destroy() { 24 // TODO Auto-generated method stub 25 26 } 27 28 @Override 29 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 30 throws IOException, ServletException { 31 32 HttpServletRequest httpRequest = (HttpServletRequest) request; 33 HttpServletResponse httpResponse = (HttpServletResponse) response; 34 HttpSession session = httpRequest.getSession(); 35 // 登陆url 36 String loginUrl = httpRequest.getContextPath() + "/login.jsp"; 37 String url = httpRequest.getRequestURI().toString(); 38 39 // 注:在pattenURL中的全部不拦截 url.indexOf(urlStr) > -1 表示urlStr在url中出现过,出现就不拦截 40 for (String urlStr : pattenURL) { 41 if (url.indexOf(urlStr) > -1) { 42 chain.doFilter(request, response); 43 return; 44 } 45 } 46 47 //超时处理,ajax请求超时设置超时状态,页面请求超时则返回提示并重定向,session.getAttribute("")是获取到登录人的session信息 48 if (session.getAttribute("") == null) { 49 // 判断是否为ajax请求 50 if (httpRequest.getHeader("x-requested-with") != null 51 && httpRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) { 52 httpResponse.addHeader("sessionstatus", "timeOut"); // 返回超时标识 53 httpResponse.addHeader("loginPath", loginUrl);// 返回url 54 chain.doFilter(request, response);// 不可少,否则请求会出错 55 } else { 56 // alert('会话过期,请重新登录'); 57 String str = "<script language='javascript'>" + "window.top.location.href='" + loginUrl + "';</script>"; 58 response.setContentType("text/html;charset=UTF-8");// 解决中文乱码 59 try { 60 PrintWriter writer = response.getWriter(); 61 writer.write(str); 62 writer.flush(); 63 writer.close(); 64 } catch (Exception e) { 65 e.printStackTrace(); 66 } 67 } 68 } else { 69 chain.doFilter(request, response); 70 } 71 } 72 73 /** 74 * 过滤器初始化调用方法 在pattenURL中的全部不拦截,所以上面会使用:path.indexOf(urlStr) > -1 75 */ 76 @Override 77 public void init(FilterConfig config) throws ServletException { 78 pattenURL.add("login.jsp");// 登录jsp 79 pattenURL.add("login.do");// 登录方法 80 pattenURL.add("css");// css 81 pattenURL.add("image");// image 82 pattenURL.add("js");// js 83 pattenURL.add("fonts");// fonts 84 85 } 86 87 }
- 在web.xml中注册过滤器
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 5 6 <display-name>test-login</display-name> 7 8 <!-- 登录过滤器 --> 9 <filter> 10 <description>登录过滤器</description> 11 <filter-name>loginFilter</filter-name> 12 <filter-class>com.test.login.LoginFilter</filter-class> 13 </filter> 14 <filter-mapping> 15 <filter-name>loginFilter</filter-name> 16 <url-pattern>/*</url-pattern> 17 </filter-mapping> 18 19 <welcome-file-list> 20 <welcome-file>index.jsp</welcome-file> 21 </welcome-file-list> 22 23 </web-app>
- 引入一个全局的js。用户控制ajax请求,如果是ajax请求的话,跳转到登录界面。js代码主要是真对所有ajax请求进行跳转的,所以如果有的ajax不想被过滤拦截,则只需要写上:global:false即可不被拦截到
1 /* 2 * 说明:此处是调用ajax方法时,判断session是否过期 3 * 4 * 注:如果不想让ajax方法受这个影响,可以在ajax方法中写: global:false 5 * 如下: 6 * $.ajax({ 7 * url:"test.html", 8 * global:false //不触发全局ajax事件 9 * }) 10 * 11 * **/ 12 13 $(document).ajaxComplete(function(event, xhr, settings) { 14 if(xhr.getResponseHeader("sessionstatus")=="timeOut"){ 15 if(xhr.getResponseHeader("loginPath")){ 16 alert("登录过期,请重新登录..."); 17 window.location.replace(xhr.getResponseHeader("loginPath")); 18 }else{ 19 //alert("请求超时请重新登陆 !"); 20 } 21 } 22 });