Filter过滤器实现自动登录

Filter介绍
问题:Filter是什么,它能做什么?
    1.从两个方面来解析Filter是什么?
       1.功能  可以帮助我们对请求与响应操作进行过滤。
       2.技术  Sun公司定义的一个接口,javax.servlet.Filter

   2.Filter能完成什么操作?
       常用示例:
       1.通用编码过滤器.
       2.粗粒度的权限控制(url级别)
       3.过滤一些敏感字

Filter创建步骤:
        1.创建一个类实现javax.servlet.Filter接口。
        2.重写Filter接口中三个方法  init  doFilter  destroy.
        3.在web.xml文件中配置Filter

为什么在web.xml文件中配置Filter?
        1.Filter也是一个资源,也要被服务器加载,所以要在web.xml文件中配置.

        2.我们在web.xml文件中配置Filter的另一个目的是用来设置Filter拦截什么资源。


实例:需求:网站登录的时候当用户勾选自动登录选框之后,当用户再来登录,自动登录进网站。

      准备:简单的模拟如下页面:

     

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title></title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	  </head>
  <body>
    <h3>这里是最美网</h3>
	    <c:if test="${ not empty existUser}">	    
	    	<h2>欢迎您:${existUser.nickname }</h2>
	    </c:if>
	    <c:if test="${empty existUser }">
	    	<a href="${pageContext.request.contextPath }/login.jsp">请登录</a>
	    </c:if>
    <h3>新闻标题</h3>
    <h2>大阅兵</h2>
  </body>
</html>

    
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title></title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	  </head>
  <body>
  <form action="${pageContext.request.contextPath }/login" method="post">
	    <p style="color:red">${msg }</p>
	    用户名:<input type="text" id="username" name = "username"><br>
	    密码:<input type="password" id="password" name="password"><br>
	    <input type="checkbox" name="autologin" value="auto_ok">自动登录<br>
	    <button type="submit" value="登录">登录</button>
    </form>
  </body>
</html>

   过滤器:

public class myFilter implements Filter {

	public void destroy() {
		
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		
		/**
		 * 从session中获取existUser
		 * 如果不为空,说明已经登录并且没有关闭浏览器,放行
		 * 如果为空说明没有登录,获取指定名称的cookie
		 *   *如果找不到该cookie说明用户没有开启自动登录功能 ,放行
		 *   *如果不为空,从cookie中拿到用户名和密码从数据库中查询
		 *    *如果查不到 ,则用户名或密码改变了,不处理  放行
		 *    *如果查到了放到session中,放行
		 * 
		 */
		
		//从session中获取用户existUser
		HttpServletRequest req =(HttpServletRequest) request ;
		HttpSession session = req.getSession();
		User existUser  =(User) session.getAttribute("existUser");
		
		if (existUser!=null) {
			
			chain.doFilter(req, response);
			
		}else {
			//为空,说明没有登录
			//获取指定cookie
			//获取保存cookie的数组
		    Cookie []cookies =	req.getCookies();
		    
		    Cookie cookie =MyCookieUtile.findCookieByName(cookies, "autologin");
		    
		    //判断cookie是否为空
		    if (cookie==null) {
		    	
		    	chain.doFilter(req, response);
				
			}else{
				
				//获取cookie的value值
				String value = cookie.getValue();
				String username = value.split(":")[0];
				String password = value.split(":")[1];
				
				//拿到cookie中的用户名和密码去数据库中查
				UserDao dao = new UserDao();
				
				try {
					User user = dao.checkUser(username, password);
					
					if (user==null) {
						chain.doFilter(req, response);
					}else{
						//说明成功,自动登录
						session.setAttribute("existUser",user);
						//放行
						chain.doFilter(req, response);
						
					}
					
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}   		        
		    
		}
		
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

}
       
public class MyCookieUtile {
	
	/**
	 * 通过传入的cookie名称从传入的cookie数组中查找cookie
	 * 如果数组为空,则没有找到返回为null
	 * 如果不为空,找到返回cookie
	 * @param cookies
	 * @param cookiename
	 * @return
	 */	
	public static Cookie findCookieByName(Cookie []cookies,String cookiename){
		
		if (cookies==null) {
			return null;			
		}else{	
			
			for (Cookie cookie : cookies) {
				//获取cookie的名称和传入的名称对比
				if (cookiename.equals(cookie.getName()) ) {
					//相同则返回
					return cookie;					
				}
			}
			return null;
		}				
	}
}

     servlet:

public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		/**
		 * 接收参数
		 * 根据用户名和密码查询数据库
		 * 如果成功,返回到content页
		 * 如果不成功,返回登录页继续登录
		 */
		//解决中文乱码问题
		request.setCharacterEncoding("UTF-8");		
		String username = request.getParameter("username");
		String password = request.getParameter("password");		
		//调用dao层查询
		UserDao dao = new UserDao();
		try {
			User existUser = dao.checkUser( username, password);
			
			if (existUser==null) {
				request.setAttribute("msg", "用户名或密码错误");
				request.getRequestDispatcher("/login.jsp").forward(request, response);
				
			}else{
				//登录成功
				
				//回写cookie
				String autologin = request.getParameter("autologin");
				
				if ("auto_ok".equals(autologin)) {
					
					String value = username+":"+password;
					Cookie cookie = new Cookie("autologin", value);					
					//设置有效时间
					cookie.setMaxAge(60*60);
					//设置有效路径
					cookie.setPath("/");					
					//回写到客户端
					response.addCookie(cookie);		
					
				}				
				request.getSession().setAttribute("existUser", existUser);				
				
				//重定向到content页面
				response.sendRedirect(request.getContextPath()+"/content.jsp");
				
			}				
			
		} catch (SQLException e) {
			e.printStackTrace();
		}		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);

	}
}


         最后在配置文件中web.xml文件中配置filter。这样当用户勾选了自动登录,关闭浏览器之后,再次访问即可自动登录进网站。

      在我们创建一个Filter时,要重写接口中的方法,有一个方法doFilter,它就是用于拦截操作的方法。在配置Filter时,可以指定拦截什么资源,当浏览器访问这个资源时,Filter的doFilter方法就会执行拦截操作。

      我们如果在Filter中,它的doFilter方法执行了,代表拦截操作开始了,如果想要让其可以继续向下访问资源,就需要通过doFilter方法的第三个参数FilterChain类型,调用它的doFilter方法,完成向下执行操作。

      总结:

   1.在Filter中具体的拦截操作是由doFilter方法执行的。  如果要想访问资源,需要chain.doFilter()放行.
   2.拦截什么资源是由web.xml文件中配置的Filter确定的。



评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值