java编程:如何使用过滤器和cookie技术来完成用户自动登陆功能?
要想完成自动登陆,首先要完成基本的登陆
登陆页面是login.jsp
点击登陆则运行loginServlet,获取用户名密码,逐渐通过service传递到dao,dao层根据根据用户名和密码去查找,将查找的结果封装成一个user对象,并通过service返回到servlet,service判断这个user对象是否为空,如果为空,则重定向到首页,如果不是空,放入session(方便以后其它地方用的到),然后转发到网站首页request.getContextPath()
代码
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>会员登录</title>
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
<script src="js/jquery-1.11.3.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<!-- 引入自定义css文件 style.css -->
<link rel="stylesheet" href="css/style.css" type="text/css" />
<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>
<!-- 引入header.jsp -->
<jsp:include page="/header.jsp"></jsp:include>
<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
<div><span style="color:red;">${loginInfo }</span></div>
<form class="form-horizontal"method="post" action="${pageContext.request.contextPath }/login">
<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" id="username"
placeholder="请输入用户名" name="username">
</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" id="inputPassword3"
placeholder="请输入密码" name="password">
</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"
placeholder="请输入验证码">
</div>
<div class="col-sm-3">
<img src="./image/captcha.jhtml" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label> <input type="checkbox"> 自动登录
</label> <label> <input
type="checkbox"> 记住用户名
</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"
style="background: url('./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>
<!-- 引入footer.jsp -->
<jsp:include page="/footer.jsp"></jsp:include>
</body>
</html>
header.jsp
这个是否登陆了,如果登陆了,则
如果没有登陆则
looginServlet
package com.huanfeng.web;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.huanfeng.domain.User;
import com.huanfeng.service.LoginService;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
LoginService service=new LoginService();
HttpSession session = request.getSession();
User user=null;
try {
user=service.login(username,password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(user!=null) {
session.setAttribute("user", user);
response.sendRedirect(request.getContextPath());//重定向到首页
}else {
request.setAttribute("loginInfo", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
判断返回结果,如果为空表示没有查找到,我们重定向到首页,如果有则将数据存入session域,并且重定向到首页,表示登陆
loginservice
package com.huanfeng.service;
import java.sql.SQLException;
import com.huanfeng.dao.LoginDao;
import com.huanfeng.domain.User;
public class LoginService {
public User login(String username, String password) throws SQLException {
LoginDao dao=new LoginDao();
User user=dao.login(username,password);
return user;
}
}
logindao
package com.huanfeng.dao;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import com.huanfeng.domain.User;
import com.huanfeng.utils.DataSourceUtils;
public class LoginDao {
public User login(String username, String password) throws SQLException {
QueryRunner runner=new QueryRunner(DataSourceUtils.getDataSource());
String sql="select * from loginuser where username= ? and password=?";
User user=runner.query(sql, new BeanHandler<User>(User.class),username,password);
return user;
}
}
至此登陆就完成了,那么如何才能完成自动登陆呢?
就比如头条,登陆一次,一个月都不用登陆,点开头条官网直接登陆了,这个是怎么做到的,首先用户勾选自动登陆之后,应该把用户信息持久化到磁盘,使用cookie,设置存活时间一个月,然后以后只要用户访问这个网站,我们就用filter拦一下,获取cookie,如果cookie有这个用户信息,那就直接表示登陆,并把用户信息当到session中,以后的页面只要session中有数据,就${useer}从session中取,显示某某登陆
loginServlet更改代码
package com.huanfeng.web;
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 com.huanfeng.domain.User;
import com.huanfeng.service.LoginService;
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String autoLogin = request.getParameter("autoLogin");
HttpSession session=request.getSession();
LoginService service=new LoginService();
User user=null;
try {
user=service.login(username, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(user!=null) {
if(autoLogin!=null) {
String username_code = URLEncoder.encode(username, "UTF-8");
System.out.println("username_code"+username_code);
Cookie cookie_username=new Cookie("cookie_username",username_code);
Cookie cookie_password=new Cookie("cookie_password",password);
cookie_username.setMaxAge(60*60);
cookie_password.setMaxAge(60*60);
cookie_username.setPath(request.getContextPath());
cookie_password.setPath(request.getContextPath());
response.addCookie(cookie_username);
response.addCookie(cookie_password);
}
session.setAttribute("user", user);
response.sendRedirect(request.getContextPath());
}else {
request.setAttribute("loginInfo", "账号或密码错误");
request.getRequestDispatcher(request.getContextPath()+"/login.jsp");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
QuickFilter
package com.huanfeng.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 com.huanfeng.domain.User;
import com.huanfeng.service.LoginService;
public class QuickFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//filter的作用就是登陆一下,提前登陆一下,登陆的用户名密码从cookie中取
HttpServletRequest req=(HttpServletRequest)request;
HttpServletResponse res=(HttpServletResponse)response;
HttpSession session=req.getSession();
Cookie[] cookies=req.getCookies();
User user=null;
LoginService service=new LoginService();
String username=null;
String password=null;
if(cookies!=null) {//cookie不是空的就判断其内部是否有已经登陆的用户名和密码
for(Cookie c:cookies) {//cookie中存储的都是一个一个的键值对,我们要遍历这些键值对,把键为cookie_username,和cookie_password的给拿出来,使用getname拿出来
if("cookie_username".equals(c.getName())) {
username=c.getValue();
username = URLDecoder.decode(username, "UTF-8");
System.out.println("cookie_username"+username);
}
if("cookie_password".equals(c.getName())) {
password=c.getValue();
}
}
}
if(username!=null&&password!=null) {
try {
user=service.login(username, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
session.setAttribute("user", user);
}
//最后不管user是否查找到,都放入session,ei表达式会自动判断其是否为空,就算为空${user.name}也不会出问题
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
servlet的作用就是除了基本登陆功能之外,他还有一个功能就是判断是否勾选了自动登陆
注意,自动登陆是在表单中,如果勾选了提交表单,我们才能获取到它的值,如果没有勾选则获取不到,所以我们getParameter("autoLogin"),如果值不是空的话,就算是自动登陆了。
添加之后,要发送给客户端,存在本地
注意session一定要写在if内,不能写在if外,因为一旦写在if外,那么username和password为空的时候,就说明cookie没有用户信息,而此时可能用户已经登陆了,只是没有勾选自动登陆,若此时访问其他页面,也会被filter拦截,但是cookie却没有数据,只能放一个null到session,会把当前登陆的session给覆盖,导致虽然登陆了,但是还和没有登陆一样,写在外面就会把已经登陆的信息弄成空,所以要写在里面,写在里面就算service.login返回的是null,就是没有查找到也没有关系,至成空因为cookie中有信息,数据库中没有,说明用户已经注销,当然不能登陆了
cookie不能存储字符串,所以需要编码一下,再存储
从cookie中取出还要解码一下
在实际操作中并没有编码解码,如果没有按照上面的编码解码cookie也没有出现问题,原因未知?