一、自动登录实现原理。
(1)当用户勾选“记住密码”时,先登录,然后把账号密码记录到客户端的Cookie中,下次访问任意页面的时候使用过滤器从客户端的Cookie中获取账号密码进行登录,最后把Cookie时间刷新一遍。
(2)当用户不勾选“记住密码”时,先登录,然后把Cookie从客户端中销毁。
实现步骤
1. 在登录的表单 上提交到一个 Servlet:
<form class="form-horizontal" action="${ pageContext.request.contextPath }/UserServlet" method="post"> <input type="hidden" name="method" value="login"> <!-- 提交是post方式 所以传递参数的用隐藏项 --> 传递UserServlet中 login方法
2.在UserServlet 的login()方法中 当登录成功后把 用户信息保存到Cookie中
// 登录成功:自动登录 功能 String autoLogin = req.getParameter("autoLogin"); //当用户勾选“记住密码”时 会把value的值传递过来 在这获取 if ("true".equals(autoLogin)) { Cookie cookie = new Cookie("autoLogin",existUser.getUsername()+"#"+existUser.getPassword()); //把用户信息保存到Cookie中 cookie.setPath("/项目名"); cookie.setMaxAge(60*60*24*7); //设置持久化为 保留7天 resp.addCookie(cookie); //写回浏览器 最后还把 用户信息存入Session中 }
3.在过滤器中 获取Session和Cookie中的用户信息 决定是否让其登录
判断session中是否有用户的信息: //这是判断用户是否关闭浏览器 关闭浏览器后 session中没有 * * session中如果有:放行. * * session中没有: * * 从Cookie中获取: * * Cookie中没有:放行. * * Cookie中有: * * 获取Cookie中存的用户名和密码到数据库查询. * * 没有查询到:放行. * * 查询到:将用户信息存入到session . 放行.
二、自动登录简单案例。
抽取出来一个处理过的Servlet BaseServlet
package com.itheima.stort.utils; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 通用的SErvlet的编写: * @author admin * */ @SuppressWarnings("all") public class BaseServlet extends HttpServlet{ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 接收参数: request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); String methodName = request.getParameter("method"); if (methodName==null || "".equals(methodName)) { response.getWriter().print("你访问的不存在"); return; } // 获得子类的Class对象: Class clazz= this.getClass(); // 获得子类中的方法了: try { Method method = clazz.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); //执行该方法 返回字符串 作为转发路径 String path = (String) method.invoke(this, request,response); if (path!=null) { request.getRequestDispatcher(path).forward(request, response);; } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
登录的Servlet: 只有登录功能实现后才能自动登录
package com.itheima.stort.web.servlet; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; import java.util.Date; import java.util.Map; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.ConvertUtils; import com.itheima.stort.domian.User; import com.itheima.stort.service.UserService; import com.itheima.stort.service.impl.UserServiceImpl; import com.itheima.stort.utils.BaseServlet; import com.itheima.stort.utils.MyDateConverter; /** * 用户模块的Servlet: */ public class UserServlet extends BaseServlet{ private static final long serialVersionUID = 1L; /** * 跳转到注册页面的执行的方法:registUI */ public String registUI(HttpServletRequest req,HttpServletResponse resp){ return "/jsp/register.jsp"; } /** * 异步校验用户名的执行的方法: checkUsername */ public String checkUsername(HttpServletRequest req,HttpServletResponse resp){ try { //接受参数 String username = req.getParameter("username"); //调用业务层 UserService user = new UserServiceImpl(); User eixtuser = user.findByUsername(username); if (eixtuser==null) { // 用户名可以使用: resp.getWriter().print("1"); } else { //用户名不可以使用 resp.getWriter().print("2"); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * 用户注册的执行的方法:regist */ public String regist(HttpServletRequest req,HttpServletResponse resp){ try { //接受参数 Map<String, String[]> map = req.getParameterMap(); // 封装数据: User user = new User(); //把页面接受的String日期类型 转换成 Data类型的日期 ConvertUtils.register(new MyDateConverter(), Date.class); //调用beanutils工具 封装数据 BeanUtils.populate(user, map); // 调用业务层: UserService userService = new UserServiceImpl(); userService.save(user); // 页面跳转: req.setAttribute("smg", user.getName()+",注册成功!请去邮箱激活!"); return "/jsp/smg.jsp"; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(); } } /** * 用户激活的方法: * @param req * @param resp */ public String active(HttpServletRequest req,HttpServletResponse resp){ //接受激活码 String code = req.getParameter("code"); // 根据激活码查询: UserService userService = new UserServiceImpl(); User existuser; try { existuser = userService.findBycode(code); System.out.println(existuser); //判断 if (existuser==null) {//激活码为错误 req.setAttribute("smg", "激活码错误!请重新激活"); }else{ //操作激活码 existuser.setState(2); existuser.setCode(null); userService.update(existuser); req.setAttribute("smg", "激活成功!请去登录!"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "/jsp/smg.jsp"; } /** * 跳转到登录页面的执行的方法:loginUI */ public String loginUI(HttpServletRequest req,HttpServletResponse resp){ return "/jsp/login.jsp"; } /** * 用户登录的执行的方法:login */ public String login(HttpServletRequest req,HttpServletResponse resp){ try { //一次性验证码程序: String code1 = req.getParameter("code"); String code2 = (String) req.getSession().getAttribute("code"); req.getSession().removeAttribute("code"); //判断用户输入的验证码跟生成的验证码是否一致 if (!code1.equalsIgnoreCase(code2)) { req.setAttribute("smg", "验证码输入错误!"); return "/jsp/login.jsp"; } // 接收参数: Map<String, String[]> map = req.getParameterMap(); //封装数据 User user = new User(); BeanUtils.populate(user, map); // 调用业务层: UserService userService = new UserServiceImpl(); User existUser = userService.login(user); if (existUser==null) { req.setAttribute("smg", "用户名或密码或用户未激活!"); return "/jsp/login.jsp"; } else { // 登录成功:自动登录 功能 String autoLogin = req.getParameter("autoLogin"); if ("true".equals(autoLogin)) { Cookie cookie = new Cookie("autoLogin",existUser.getUsername()+"#"+existUser.getPassword()); cookie.setPath("/store_v2.0"); cookie.setMaxAge(60*60*24*7); resp.addCookie(cookie); } // 记住用户名: 功能 String remember = req.getParameter("remember"); if ("true".equals(remember)) { Cookie cookie = new Cookie("username",existUser.getUsername()); cookie.setPath("/store_v2.0"); cookie.setMaxAge(24 * 60 * 60); resp.addCookie(cookie); } //页面跳转 req.getSession().setAttribute("existUser",existUser ); resp.sendRedirect(req.getContextPath()+"/index.jsp"); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * 用户退出功能的方法:logOut * @param req * @param resp * @return */ public String logOut(HttpServletRequest req,HttpServletResponse resp){ req.getSession().invalidate(); try { //清除session resp.sendRedirect(req.getContextPath()+"/index.jsp"); // 清空自动登录的Cookie: Cookie cookie = new Cookie("autoLogin","" ); cookie.setPath("/store_v2.0"); cookie.setMaxAge(0); resp.addCookie(cookie); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
在filter过滤器中实现自动登录
package com.itheima.stort.web.filter; import java.io.IOException; import java.sql.SQLException; 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.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import com.itheima.stort.domian.User; import com.itheima.stort.service.UserService; import com.itheima.stort.service.impl.UserServiceImpl; import com.itheima.stort.utils.CookieUtils; /** * 自动登录的过滤器的实现 * @author admin * */ public class AutoLoginFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { /** * 判断session中是否有用户的信息: * * session中如果有:放行. * * session中没有: * * 从Cookie中获取: * * Cookie中没有:放行. * * Cookie中有: * * 获取Cookie中存的用户名和密码到数据库查询. * * 没有查询到:放行. * * 查询到:将用户信息存入到session . 放行. */ // 判断session中是否有用户的信息: HttpServletRequest req = (HttpServletRequest) request; HttpSession session = req.getSession(); User existUser = (User) session.getAttribute("existUser"); if(existUser != null){ // session中有用户信息. chain.doFilter(req, response); }else{ // session中没有用户信息. // 获得Cookie的数据: Cookie[] cookies = req.getCookies(); Cookie cookie = CookieUtils.findCookie(cookies, "autoLogin"); // 判断Cookie中有没有信息: if(cookie == null){ // 没有携带Cookie的信息过来: chain.doFilter(req, response); }else{ // 带着Cookie信息过来. String value = cookie.getValue();// aaa#111 // 获得用户名和密码: String username = value.split("#")[0]; String password = value.split("#")[1]; // 去数据库进行查询: User user = new User(); user.setUsername(username); user.setPassword(password); UserService userService = new UserServiceImpl(); try { existUser = userService.login(user); if(existUser == null){ // 用户名或密码错误:Cookie被篡改的. chain.doFilter(req, response); }else{ // 将用户存到session中,放行 session.setAttribute("existUser", existUser); chain.doFilter(req, response); } } catch (SQLException e) { e.printStackTrace(); } } } } @Override public void destroy() { } }
自动登录的页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>会员登录</title> <link rel="stylesheet" href="${ pageContext.request.contextPath }/css/bootstrap.min.css" type="text/css" /> <script src="${ pageContext.request.contextPath }/js/jquery-1.11.3.min.js" type="text/javascript"></script> <script src="${ pageContext.request.contextPath }/js/bootstrap.min.js" type="text/javascript"></script> <!-- 引入自定义css文件 style.css --> <link rel="stylesheet" href="css/style.css" type="text/css"/> <script type="text/javascript"> $(function(){ $("#img1").click(function(){ $(this).prop("src","${ pageContext.request.contextPath }/CheckImgServlet?time="+new Date().getTime()); }); }); </script> <style> body{ margin-top:20px; margin:0 auto; } .carousel-inner .item img{ 100%; height:300px; } .container .row div{ /* position:relative; float:left; */ } font { color: #666; font-size: 22px; font-weight: normal; padding-right:17px; } </style> </head> <body> <%@include file="menu.jsp" %> <div class="container" style="100%;height:460px;background:#FF2C4C url('images/loginbg.jpg') no-repeat;"> <div class="row"> <div class="col-md-7"> <!--<img src="./image/login.jpg" width="500" height="330" alt="会员登录" title="会员登录">--> </div> <div class="col-md-5"> <div style="440px;border:1px solid #E7E7E7;padding:20px 0 20px 30px;border-radius:5px;margin-top:60px;background:#fff;"> <font>会员登录</font>USER LOGIN ${smg } <div> </div> <form class="form-horizontal" action="${ pageContext.request.contextPath }/UserServlet" method="post"> <input type="hidden" name="method" value="login"> <!-- 提交是post方式 所以传递参数的用隐藏项 --> <div class="form-group"> <label for="username" class="col-sm-2 control-label">用户名</label> <div class="col-sm-6"> <input type="text" class="form-control" name="username" id="username" value="${ cookie.username.value }" placeholder="请输入用户名"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">密码</label> <div class="col-sm-6"> <input type="password" class="form-control" name="password" id="inputPassword3" placeholder="请输入密码"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">验证码</label> <div class="col-sm-3"> <input type="text" class="form-control" id="inputPassword3" name="code" placeholder="请输入验证码"> </div> <div class="col-sm-3"> <img id="img1" src="${ pageContext.request.contextPath }/CheckImgServlet"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <div class="checkbox"> <label> <input type="checkbox" name="autoLogin" value="true"> 自动登录 //我们必须在自动登录 这设置 naem和value </label> <label> <input type="checkbox" name="remember" value="true"> 记住用户名 </label> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" width="100" value="登录" name="submit" border="0" style="background: url('${ pageContext.request.contextPath }/images/login.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0); height:35px;100px;color:white;"> </div> </div> </form> </div> </div> </div> </div> <div style="margin-top:50px;"> <img src="${ pageContext.request.contextPath }/image/footer.jpg" width="100%" height="78" alt="我们的优势" title="我们的优势" /> </div> <div style="text-align: center;margin-top: 5px;"> <ul class="list-inline"> <li><a>关于我们</a></li> <li><a>联系我们</a></li> <li><a>招贤纳士</a></li> <li><a>法律声明</a></li> <li><a>友情链接</a></li> <li><a target="_blank">支付方式</a></li> <li><a target="_blank">配送方式</a></li> <li><a>服务声明</a></li> <li><a>广告声明</a></li> </ul> </div> <div style="text-align: center;margin-top: 5px;margin-bottom:20px;"> Copyright © 2005-2016 传智商城 版权所有 </div> </body></html>