一、自動登錄實現原理。
(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>
