一、自动登录实现原理。
(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>
浙公网安备 33010602011771号