一、自動登錄實現原理。
(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{ width: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="width: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="width: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;width: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>