步骤分析:
步骤分析: 1.数据库和表 create database day16; use day16; create table user( id int primary key auto_increment, username varchar(20), password varchar(20) ); insert into user values(null,'tom','123'); 2.web项目 jar包 工具类 配置文件 3.新建一个登录页面 表单 4.表单提交 loginservlet 接受用户名和密码 调用service完成登录操作,返回值User 判断user是否为空 若不为空,将user放入session中 判断是否勾选了自动登录 若勾选了: 需要将用户名和密码写回浏览器 5.下次访问网站的时候 过滤器拦截任意请求 判断有无指定的cookie 有cookie,获取用户名和密码 调用service完成登录操作,返回user 当user不为空的时候将user放入session中. 当我们换用jack登录的时候发现登录不了 自动登录只需要登录一次:当session中没有用户的时候 访问有些资源是不需要自动登录的(和登录还有注册相关的资源) 修改filter的逻辑: 首先判断session中是否有user 若没有 并且访问的路径不是和登录注册相关的时候 才去获取指定的cookie
项目结构:
项目展示:
数据库:
/* SQLyog Ultimate v12.09 (64 bit) MySQL - 5.5.53 : Database - autologin ********************************************************************* */ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; CREATE DATABASE /*!32312 IF NOT EXISTS*/`autologin` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `autologin`; /*Table structure for table `user` */ DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `username` varchar(255) DEFAULT NULL COMMENT '用户名', `password` varchar(255) DEFAULT NULL COMMENT '密码', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; /*Data for the table `user` */ insert into `user`(`id`,`username`,`password`) values (1,'tom','123'),(2,'jack','123'); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
项目代码:
com.gordon.constant:
--
package com.gordon.constant; public class Constant { /** * 是否自动登录 */ public static String IS_AUTO_LOGIN = "ok"; /** * 是否记住用户名 */ public static String IS_REMEMBER_USER = "ok"; }
com.gordon.dao:
--UserDao.java:
package com.gordon.dao; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import com.gordon.domain.User; import com.gordon.utils.DataSourceUtil; public class UserDao { /** * 用户登录 * * @param username * @param password * @return * @throws SQLException */ public User login(String username, String password) throws SQLException { QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSource()); String sql = "select * from user where username = ? and password = ? limit 1"; return qr.query(sql, new BeanHandler<User>(User.class), username, password); } }
com.gordon.domain:
--User.java:
package com.gordon.domain; public class User { private int id; private String username; private String password; public User() { } public User(int id, String username, String password) { this.id = id; this.username = username; this.password = password; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
com.gordon.service:
--UserService.java:
package com.gordon.service; import java.sql.SQLException; import com.gordon.dao.UserDao; import com.gordon.domain.User; public class UserService { /** * 用户登录 * @param username * @param password * @return * @throws SQLException */ public User login(String username, String password) throws SQLException { return new UserDao().login(username, password); } }
com.gordon.utils:
--CookieUtil.java
package com.gordon.utils; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Cookie工具类 * */ public class CookieUtil { /** * 添加cookie * * @param response * @param name * @param value * @param maxAge */ public static void addCookie(HttpServletResponse response, String name, String value) { Cookie cookie = new Cookie(name, value); cookie.setPath("/"); response.addCookie(cookie); } /** * 添加cookie * * @param response * @param name * @param value * @param maxAge */ public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) { Cookie cookie = new Cookie(name, value); cookie.setPath("/"); if (maxAge > 0) { cookie.setMaxAge(maxAge); } response.addCookie(cookie); } /** * 删除cookie * * @param response * @param name */ public static void removeCookie(HttpServletResponse response, String name) { Cookie uid = new Cookie(name, null); uid.setPath("/"); uid.setMaxAge(0); response.addCookie(uid); } /** * 获取cookie值 * * @param request * @return */ public static String getUid(HttpServletRequest request, String cookieName) { Cookie cookies[] = request.getCookies(); for (Cookie cookie : cookies) { if (cookie.getName().equals(cookieName)) { return cookie.getValue(); } } return null; } }
--DataSourceUtil.java:
package com.gordon.utils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class DataSourceUtil { private static ComboPooledDataSource ds = new ComboPooledDataSource(); /** * 获取数据源 * * @return 连接池 */ public static DataSource getDataSource() { return ds; } /** * 获取连接 * * @return 连接 * @throws SQLException */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } /** * 释放资源 * * @param conn * 连接 * @param st * 语句执行者 * @param rs * 结果集 */ public static void closeResource(Connection conn, Statement st, ResultSet rs) { closeResultSet(rs); closeStatement(st); closeConn(conn); } /** * 释放连接 * * @param conn * 连接 */ public static void closeConn(Connection conn) { if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } conn = null; } } /** * 释放语句执行者 * * @param st * 语句执行者 */ public static void closeStatement(Statement st) { if (st != null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } st = null; } } /** * 释放结果集 * * @param rs * 结果集 */ public static void closeResultSet(ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } rs = null; } } }
com.gordon.web.filter:
--AutoLoginFilter.java
package com.gordon.web.filter; import java.io.IOException; import java.net.URLDecoder; 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.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.gordon.domain.User; import com.gordon.service.UserService; import com.gordon.utils.CookieUtil; /** * 自动登录过滤器 */ @WebFilter(urlPatterns = { "/*" }) public class AutoLoginFilter implements Filter { public AutoLoginFilter() { } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; // 判断用户是否已经登录,如果不存在user,则未登录,开始自动登录 if (req.getSession().getAttribute("user") == null) { // 判断是否存在cookie if (CookieUtil.getUid(req, "autologin") != null) { // 排除指定的路径(指定路径下不需要自动登录,如登录请求,注册请求) if (!req.getServletPath().contains("/login")) { System.out.println("执行了自动登录操作......"); // 获取cookie中的用户名密码 String userCookieValue = CookieUtil.getUid(req, "autologin"); String username = userCookieValue.split("-")[0]; String password = userCookieValue.split("-")[1]; User user = null; try { user = new UserService().login(URLDecoder.decode(username, "UTF-8"), password); } catch (Exception e) { e.printStackTrace(); } if (user != null) { // 将user放入session req.getSession().setAttribute("user", user); // 直接转入成功页面,不需要自动传递 resp.sendRedirect(req.getContextPath() + "/"); } } } } chain.doFilter(request, response); } public void init(FilterConfig fConfig) throws ServletException { } }
com.gordon.web.servlet:
--LoginServlet.java
package com.gordon.web.servlet; import java.io.IOException; import java.net.URLEncoder; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.gordon.constant.Constant; import com.gordon.domain.User; import com.gordon.service.UserService; import com.gordon.utils.CookieUtil; /** * 用户登录 */ @WebServlet("/login") 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"); String username = request.getParameter("username"); String password = request.getParameter("password"); String autologin = request.getParameter("autologin"); String rememberuser = request.getParameter("rememberuser"); User user = null; try { user = new UserService().login(username, password); } catch (SQLException e) { e.printStackTrace(); } if (user != null) { // 将user放入session request.getSession().setAttribute("user", user); // 如果开启记住用户名,将用户名称存入cookie if (rememberuser != null && Constant.IS_REMEMBER_USER.equals(rememberuser)) { // 记住用户名cookie存储60天 CookieUtil.addCookie(response, "rememberuser", URLEncoder.encode(user.getUsername(), "UTF-8"), 60 * 24 * 3600); } // 如果开启自动登录,将用户存入cookie if (autologin != null && Constant.IS_AUTO_LOGIN.equals(autologin)) { // 自动登录Cookie存储30天 CookieUtil.addCookie(response, "autologin", URLEncoder.encode(user.getUsername(), "UTF-8") + "-" + user.getPassword(), 30 * 24 * 3600); } } response.sendRedirect(request.getContextPath() + "/"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
--LogoutServlet.java
package com.gordon.web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.gordon.utils.CookieUtil; /** * 用户登录 */ @WebServlet("/logout") public class LogoutServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getSession().removeAttribute("user"); CookieUtil.removeCookie(response, "autologin"); response.sendRedirect(request.getContextPath() + "/"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
c3p0-config.xml:
<c3p0-config> <!-- 默认配置,如果没有指定则使用这个配置 --> <default-config> <!-- 基本配置 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/autologin</property> <property name="user">root</property> <property name="password">root</property> <!--扩展配置--> <property name="checkoutTimeout">30000</property> <property name="idleConnectionTestPeriod">30</property> <property name="initialPoolSize">10</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> <property name="maxStatements">200</property> </default-config> <!-- 命名的配置 --> <named-config name="itcast"> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/xxxx</property> <property name="user">root</property> <property name="password">1234</property> <!-- 如果池中数据连接不够时一次增长多少个 --> <property name="acquireIncrement">5</property> <property name="initialPoolSize">20</property> <property name="minPoolSize">10</property> <property name="maxPoolSize">40</property> <property name="maxStatements">20</property> <property name="maxStatementsPerConnection">5</property> </named-config> </c3p0-config>
-----------------------------------------------------
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!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>Insert title here</title> </head> <body> <c:set var="username" value="${ sessionScope.user.username }"></c:set> <c:choose> <c:when test="${ not empty username }"> 网站首页:欢迎您的使用:${ username } | <a href="${ pageContext.request.contextPath }/logout">退出登录</a> </c:when> <c:otherwise> 您还没有登录,请登录:<a href="${ pageContext.request.contextPath }/login.jsp">登录</a> </c:otherwise> </c:choose> </body> </html>
login.jsp
<%@ 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>Insert title here</title> </head> <body> <form action="${ pageContext.request.contextPath }/login" method="post"> <table> <tr> <td>用户名:</td> <td><input type="text" name="username" value="${ cookie.rememberuser.value }" /></td> </tr> <tr> <td>密码:</td> <td><input type="text" name="password" /></td> </tr> <tr> <td><input type="checkbox" name="rememberuser" value="ok" />记住用户名</td> <td><input type="checkbox" name="autologin" value="ok" />自动登录</td> </tr> <tr> <td colspan="2"><input type="submit" value="登录" /></td> </tr> </table> </form> </body> </html>
show_product.jsp
<%@ 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>Insert title here</title> </head> <body> 商品展示:欢迎您的使用:${ sessionScope.user.username } | <a href="${ pageContext.request.contextPath }/logout">退出登录</a> </body> </html>