实现用户自动登录的过滤器
当用户登录的时候勾选了自动登录选项,那么首次登录会把用户的账户密码保存到Cookie,当用户退出登录后重新访问某些页面,符合条件的将会先被filter拦截实现自动登录的功能,即使用户关闭浏览器了,只要Cookie没有过期,再次打开页面如果符合条件也是可以完成自动登录的.
需要注意的是,如果用户点击了退出登录后返回的页面(一般都是通过重定向返回的),如果返回的页面仍然被自动登录的filter所匹配,那么就会造成退出不了的死循环,因为退出成功后重定向也会被再次拦截,拦截又被自动登录了.解决办法就是在退出登录的时候通过session保存一个标记,然后被filter拦截后再取出这个标记判断,如果是来自退出登录页的则不做自动登录操作.
filter代码如下:
package blog.csdn.net.web.filter;
import java.io.IOException;
import java.net.URLDecoder;
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.HttpServletResponse;
import javax.servlet.http.HttpSession;
import blog.csdn.net.web.domain.User;
import blog.csdn.net.web.service.UserService;
import blog.csdn.net.web.util.CookieUtils;
import blog.csdn.net.web.util.StringUtils;
/**
* 处理自动登录的Filter,当用户登录的时候勾选了自动登录,用户退出登录后,下次访问,会判断cookie中保存的用户名密码完成自动登录
*
* @author mChenys
*
*/
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 {
// 强转
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
HttpSession session = httpServletRequest.getSession();
// 获取session域中保存的user
User user =null;
if(null !=session.getAttribute("user")&&
(user= (User) session.getAttribute("user")) ==null) {
// 获取为null表示用户已经退出了登录
// 避免刚刚退出登录的时候重定向到首页又被拦截了,所以从header中获取标记判断
boolean isFromLogout = false;
if(null !=session.getAttribute("isLogout")) {
isFromLogout = (boolean) session.getAttribute("isLogout");
}
if (!isFromLogout) {
// 判断用户访问的页面是否需要自动登录,这里除了访问登录和退出的请求都需要完成自动登录
// 否则访问登录的永远都是上次勾选自动登录的账户,访问退出登录永远都退不了
String path = httpServletRequest.getRequestURI();
if (!path.contains("/login") && !path.contains("/logout")) {
// 获取cookie中保存的账号和密码
Cookie loginCookie = CookieUtils.getCookieByName("autoLogin", httpServletRequest.getCookies());
if (null != loginCookie) {
// 切割用户名和密码
String username = loginCookie.getValue().split("#")[0];
String password = loginCookie.getValue().split("#")[1];
// 用户名需要解码
username = URLDecoder.decode(username, "utf-8");
// 尝试登录
try {
user = new UserService().login(username, password);
System.out.println(username + ":自动登录成功...");
} catch (SQLException e) {
e.printStackTrace();
}
if (null != user) {
// 自动登录成功,保存到session域中,避免重复自动登录
session.setAttribute("user", user);
}
}
}
}
}
// 重置下标记
session.setAttribute("isLogout", false);
// 发现
chain.doFilter(httpServletRequest, response);
}
@Override
public void destroy() {
}
}
注册filter
<!-- 自动登录拦截-->
<filter>
<filter-name>AutoLoginFilter</filter-name>
<filter-class>blog.csdn.net.web.filter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AutoLoginFilter</filter-name>
<url-pattern>/home</url-pattern>
<!--
REQUEST(默认类型):只拦截从浏览器发送来的请求,包括了重定向,因为重定向相当于让浏览器重新发送一个 新的请求
-->
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
登录的Servlet代码如下:
package blog.csdn.net.web.servlet;
import java.io.IOException;
import java.net.URLEncoder;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import blog.csdn.net.web.domain.User;
import blog.csdn.net.web.service.UserService;
import blog.csdn.net.web.util.CookieUtils;
import blog.csdn.net.web.util.StringUtils;
/**
* 用户登录
*/
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String saveName = request.getParameter("saveName");
String autoLogin = request.getParameter("autoLogin");
if (StringUtils.isEmpty(username)) {
request.setAttribute("usermsg", "用户名为空");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
if (StringUtils.isEmpty(password)) {
request.setAttribute("pwdmsg", "密码为空");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
User user = null;
try {
user = new UserService().login(username, password);
} catch (SQLException e) {
e.printStackTrace();
}
if (null == user) {
// 转发
request.setAttribute("errormsg", "用户不存在或用户名密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
} else {
// 登录成功,将用户保存到session中
HttpSession session = request.getSession();
session.setAttribute("user", user);
// 记住用户名密码
if ("on".equals(saveName)) {
// 为了可以让cookie保存中文,账号名需要编码下,页面再解码使用
Cookie saveNameCookie = new Cookie("saveName", URLEncoder.encode(username, "utf-8"));
saveNameCookie.setMaxAge(3600);
saveNameCookie.setPath(request.getContextPath() + "/");
response.addCookie(saveNameCookie);
} else {
// 清除用户名
Cookie saveNameCookie = CookieUtils.getCookieByName("saveName", request.getCookies());
if (null != saveNameCookie) {
saveNameCookie.setPath(request.getContextPath() + "/");
saveNameCookie.setMaxAge(0);
response.addCookie(saveNameCookie);
}
}
// 自动登录
if ("on".equals(autoLogin)) {
Cookie autoLoginCookie = new Cookie("autoLogin", URLEncoder.encode(username, "utf-8") + "#" + password);
autoLoginCookie.setMaxAge(3600);
autoLoginCookie.setPath(request.getContextPath() + "/");
response.addCookie(autoLoginCookie);
} else {
// 清除自动登录
Cookie autoLoginCookie = CookieUtils.getCookieByName("autoLogin", request.getCookies());
if (null != autoLoginCookie) {
autoLoginCookie.setPath(request.getContextPath() + "/");
autoLoginCookie.setMaxAge(0);
response.addCookie(autoLoginCookie);
}
}
if (user.getUsername().equals("admin")) {
response.sendRedirect(request.getContextPath() + "/productList");
} else {
response.sendRedirect(request.getContextPath() + "/home");
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
login.jsp
<%@page import="blog.csdn.net.web.util.CookieUtils"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页</title>
<style type="text/css">
.body {
margin: 20% auto 0;
width: 70%;
text-align: center;
}
.login {
width: 400px;
background-color: #cccccc;
padding: 30px 10px;
margin: auto;
}
h2 {
margin-bottom: 30px;
}
form {
padding: auto;
}
.msg {
color: red
}
table td {
padding: 10px 0px;
}
</style>
<script type="text/javascript">
function savename(){
var checkBox = document.getElementById("saveName");
checkBox.checked=!checkBox.checked;
}
function autologin(){
var checkBox = document.getElementById("autoLogin");
checkBox.checked=!checkBox.checked;
}
//显示已经记住的用户名
onload = function(){
var nameObj = document.getElementsByName("username")[0];
if(${not empty cookie.saveName}){
var username = decodeURI("${cookie.saveName.value}");
nameObj.value = username;
}
}
</script>
</head>
<body>
<div class="body">
<div class="login">
<h2>用户登录</h2>
<form action="${pageContext.request.contextPath }/login"
method="post" autocomplete="off">
<table align="center">
<tr align="left">
<td>用户名:</td>
<td>
<input type="text" name="username" maxlength="6" autocomplete="new-password"/>
<span class="msg">${usermsg}</span>
</td>
</tr>
<tr align="left">
<td>密码:</td>
<td>
<input type="password" name="password" maxlength="6" autocomplete="new-password">
<span class="msg">${pwdmsg}</span>
</td>
</tr>
<tr align="left">
<td>
<c:if test="${empty cookie.saveName}">
<input id="saveName" type="checkbox" name="saveName" />
<span onclick="savename()">记住用户名</span>
</c:if>
<c:if test="${not empty cookie.saveName}">
<input id="saveName" type="checkbox" name="saveName"
checked="checked" />
<span onclick="savename()">记住用户名</span>
</c:if>
</td>
<td>
<c:if test="${empty cookie.autoLogin}">
<input id="autoLogin" type="checkbox" name="autoLogin" />
<span onclick="autologin()">自动登录</span>
</c:if>
<c:if test="${not empty cookie.autoLogin}">
<input id="autoLogin" type="checkbox" name="autoLogin"
checked="checked" />
<span onclick="autologin()">自动登录</span>
</c:if>
</td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit" value="登录" /></td>
</tr>
</table>
</form>
<span class="msg">${errormsg}</span>
</div>
</div>
</body>
</html>
登录页效果图: