文章目录
- 任务概述
- 具体需求
- 涉及知识点
- 任务过程
- 思路及代码实现
- 一、 工具包
- properties配置文件
- DBUtils.java
- 二、 创建数据库
- 三、 对象
- User.java
- 四、 创建登录页面
- Login.jsp
- MyCSSss.css
- 五、 web登录
- 接收客户端数据LoginServlet .java
- 退出后返回登录界面LogoutServlet.java
- 六、 数据处理
- Dao.java
- 七、 登录结果页面
- Success.jsp
- Fail.jsp
- 八、 过滤器
- LoginFilter.java
- 九、 监听器
- MySessionListener.java
- 完整代码如下
- 一、 工具包
- properties配置文件
- DBUtils.java
- 二、 对象
- User.java
- 三、 创建登录页面
- Login.jsp
- MyCss.css
- 四、 web登录
- 接收客户端数据LoginServlet .java
- 退出后返回登录界面LogoutServlet.java
- 五、 数据处理
- Dao.java
- 六、 登录结果页面
- Success.jsp
- Fail.jsp
- 七、 过滤器
- LoginFilter.java
- 八、 监听器
- MySessionListener.java
任务概述
前面我们实现了用户登录功能,当时我们要求用户登录成功后,跳转到success.html 页面
现在需要做需求迭代:
1.用户登录成功后,要求跳转到success.jsp 页面,这个页面展示登录成功后的用户姓名,格式为:欢迎您,XXX,退出
2. 当用户点击退出按钮时,清除 session,跳回到登录页面
实现上述功能后,需添加一个过滤器和监听器:
过滤器: 完成上述功能后项目中无论用户是否登录成功,都可以直接访问 success.jsp,因此使用过滤器实现用户在登录情况下才能访问 success.jsp 页面
监听器: 监听 session 的变化,如果 session 每存储一次用户信息到 session则调取监听器,监听session 的数据变化
具体需求
编写登录界面并进行表单验证
实现将数据从客服端发送到服务器
通过java代码操作数据库,判断用户名和密码是否正确
创建过滤器和监听器
涉及知识点
1、sql语言及基本操作
2、JDBC(Java数据库连接)
3、自定义工具类以及properties配置文件的使用
4、JDBC连接池
5、Servlet工作原理与生命周期
6、Servlet请求与响应
7、 JSP基础知识
任务过程
- 创建数据库,保存用户名和密码
- 创建登录页面,要求用户输入用户名和密码
- 接收用户提交的用户名和密码,接收后将数据传递到数据库进行验证
- 根据验证结果,跳转到不同的结果页面(成功跳转到 success.html、失败
跳转到 false.html) - 实现对文件的过滤
- 实现session监听
思路及代码实现
一、 工具包
创建一个utils包,新建类DBUtils,新建配置文件db.properties
properties配置文件
使用ResourceBundle访问本地资源,从里面读取我们需要的值
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
username=root
password=123456
DBUtils.java
JDBC工具类,封装了操作sql的方法,因此方法都推荐静态static
- 变量定义
//定义需要的工具类对象(变量定义)
protected static Connection connection = null;
protected static PreparedStatement pps = null;//后续都是用预状态通道来实现
protected static ResultSet rs = null;//结果集
protected static int count = 0;//受影响的行数
//登录的用户名和密码
private static String username;
private static String password;
private static String url;
private static String driverName;
//Druid连接池
private static DruidDataSource druidDataSource = new DruidDataSource();
- 加载驱动
//加载驱动
static {
//Druid
ResourceBundle bundle = ResourceBundle.getBundle("db");//参数只写属性文件名,不需要写后缀
//加载属性文件
driverName = bundle.getString("driver");
url = bundle.getString("url");
username = bundle.getString("username");
password = bundle.getString("password");
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setUrl(url);
druidDataSource.setDriverClassName(driverName);
}
- 获得链接
protected static Connection getConnection() {
try {
connection = druidDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
- 得到预状态通道并绑定参数
//得到预状态通道
protected static PreparedStatement getPps(String sql) {
try {
getConnection();
pps = connection.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return pps;
}
//绑定参数,给占位符赋值,list中保存的是给占位符所赋的值
private static void setParams(List list) {
try {
if (list != null && list.size() > 0) {//集合中有内容
for (int i = 0; i < list.size(); i++) {
pps.setObject(i + 1, list.get(i));//赋值,位置从1开始所以为i+1
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
- 增删改
protected static int update(String sql, List list) {
try {
getPps(sql);//得到预状态通道
setParams(list);//绑定参数
count = pps.executeUpdate();//pps.executeUpdate()执行sql语句,返回受影响的行数
} catch (SQLException e) {
e.printStackTrace();
}
return count;//返回受影响的行数
}
- 数据查询
protected static ResultSet query(String sql, List list) {
try {
getPps(sql);//得到预状态通道
setParams(list);//绑定参数
rs = pps.executeQuery();//pps.executeUpdate()执行sql语句,返回结果集
return rs;//返回结果集
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
- 关闭资源
protected static void closeAll() {
try {
if (rs != null) {
rs.close();
}
if (pps != null) {
pps.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
二、 创建数据库
创建数据库demo,建立表user,保存用户名和密码
三、 对象
创建一个pojo包,新建类User
User类对应的数据表user,因此类属性名 = 表字段名
User.java
- 定义属性并用setter和getter设置和获取值
private String username;
private String userpassword;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpassword() {
return userpassword;
}
public void setUserpassword(String userpassword) {
this.userpassword = userpassword;
}
- 定义无参和全参构造方法
public User() {
}
public User(String username, String userpassword) {
this.username = username;
this.userpassword = userpassword;
}
- override toString()方法
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", userpassword='" + userpassword + '\'' +
'}';
}
四、 创建登录页面
Login.jsp
要求用户输入用户名和密码
- 浏览器页面主要显示
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div class="form">
<h2>用户登录</h2><br />
<!-- <form action="test" method="post"> -->
<form id="myForm" class="form-horizontal" role="form" action="/login" method="post">
<div>
<input id="username" class="inputStyle" name="username" type="text" placeholder="用户名" onblur="validateName()"/>
</div>
<span id="nameMsg"></span>
<div>
<input id="password" class="inputStyle" name="userpassword" type="password" placeholder="密码" onblur="validatePassword()"/>
</div>
<span id="passwordMsg"></span>
<div>
<input class="buttomStyle" type="submit" value="登录" />
</div>
</form>
</div>
</div>
</div>
</section>
</body>
- 表单验证
<script>
function validateName(){
var name = document.getElementById("username").value;
var msg = document.getElementById("nameMsg");
var reg = /^[\u4E00-\u9FA5]{2,4}$/;
var res = reg.test(name);
if(name == null || name == ""){
msg.innerHTML = "用户名不能为空";
msg.style.color = "red";
return false;
}else if(res == false){
msg.innerHTML = "用户名格式错误";
msg.style.color = "red";
return false;
}
return true;
}
function validatePassword(){
var name = document.getElementById("password").value;
var msg = document.getElementById("passwordMsg");
if(name == null || name == ""){
msg.innerHTML = "密码不能为空";
msg.style.color = "red";
return false;
}
return true;
}
</script>
- 使用外部样式
<link rel="stylesheet" href="MyCSS.css">
MyCSSss.css
- 登录界面总体位置
/**
* 显示水平居中
*/
section {
position: relative;
overflow: hidden;
display: flex; /*垂直居中对齐*/
justify-content: center;
align-items: center;
min-height: 100vh;
/* linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片 */
background: linear-gradient(to bottom, #f1f4f9, #dff1ff);
}
.box {
position: relative;
}
- 背景颜色
/* 背景颜色 */
.color {
/* 绝对定位 */
position: absolute;
/* 使用filter(滤镜) 属性,给图像设置高斯模糊*/
filter: blur(200px);
}
/* :nth-child(n) 选择器匹配父元素中的第 n 个子元素 */
.color:nth-child(1) {
top: -350px;
width: 600px;
height: 600px;
background:#FFC0CB;
}
.color:nth-child(2) {
bottom: -150px;
left: 100px;
width: 500px;
height: 500px;
background: #FFFFE0;
}
.color:nth-child(3) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background:#DDA0DD;
}
.color:nth-child(4) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background:#FFFFFF;
}
- 登录框样式
/* 登录框样式 */
.container {
position: relative;
width: 400px;
min-height: 400px;
background: rgba(255, 255, 255, 0.1);
display: flex;
justify-content: center;
align-items: center;
backdrop-filter: blur(5px);
box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.5);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
- 输入框样式
/* 输入框样式 */
.inputStyle{
width: 100%;
padding: 10px 20px;
margin-top: 20px;
background: rgba(255, 255, 255, 0.2);
outline: none;
border: none;
border-radius: 30px;
border: 1px solid rgba(255, 255, 255, 0.5);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
font-size: 16px;
letter-spacing: 1px;
color: #000;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}
- 登录按钮样式
/* 登录按钮样式 */
.buttomStyle{
width: 100%;
padding: 10px 20px;
max-width: 100px;
margin-top: 30px;
margin-left: 10px;
margin-bottom: 20px;
border-radius: 30px;
font-size: 16px;
letter-spacing: 1px;
background: #fff;
color: #666;
font-weight: 600;
cursor: pointer;
}
五、 web登录
接收客户端数据LoginServlet .java
创建一个web包,新建 LoginServlet 类,继承HttpServlet,接收客户端输入的用户名和密码
- override doGet方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);//当method为get时,依旧执行doPost
}
- override doPost方法接收数据
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
//取值
String username = req.getParameter("username");
System.out.println("用户输入的用户名:"+username);
String userpassword = req.getParameter("userpassword");
System.out.println("用户输入的密码:"+userpassword);
if(dao.checkLogin(username,userpassword)){
System.out.println("登陆成功");
resp.sendRedirect("/Success.html");
//req.getRequestDispatcher("/Success.html").forward(req,resp);
}else{
System.out.println("登录失败");
resp.sendRedirect("/Fail.html");
//req.getRequestDispatcher("/fail.html").forward(req,resp);
}
}
退出后返回登录界面LogoutServlet.java
- override doPost方法处理删除数据并跳转页面
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
req.getSession().invalidate();
Enumeration em = req.getSession().getAttributeNames();
while(em.hasMoreElements()){
req.getSession().removeAttribute(em.nextElement().toString());
}
// //req.getRequestDispatcher("index.jsp").forward(req,resp);
resp.sendRedirect("/login.jsp");//login.jsp
}
六、 数据处理
主要负责数据处理的模块
创建一个dao包,新建 Dao类,继承DBUtils类,使用 JDBC 完成相应数据库操作
Dao.java
public static User login(String username, String password){
System.out.println("进入check in");
String sql = "select* from user where username = ? and userpassword = ?";
ArrayList param = new ArrayList();
param.add(username);
param.add(password);
ResultSet query = query(sql, param);
try {
if(!query.next()){
System.out.println("dao:false");
return null;
}else{
User user = new User();
user.setUsername(query.getString("username"));
user.setUserpassword(query.getString("userpassword"));
System.out.println("dao:true");
return user;
}
} catch (SQLException throwables) {
System.out.println(throwables.getMessage());
return null;
}finally {
closeAll();
}
}
七、 登录结果页面
Success.jsp
<%--
Created by IntelliJ IDEA.
User: ss
Date: 2021/9/26
Time: 19:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>登陆成功</title>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="MyCSS.css">
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div>
<h2 style="color:#8B008B">欢迎登录!</h2>
<div style="margin-top: 50px ;margin-left: 90px" >
<a href="/logOut">点击退出登录</a>
</div>
</div>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
</div>
</div>
</section>
</body>
</html>
Fail.jsp
<html>
<head>
<title>登录失败</title>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="MyCSS.css">
<script>
//基本弹框
alert("用户名或密码错误,登录失败!");
</script>
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div>
<a href="/logOut">点击重新登录</a>
</div>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
</div>
</div>
</section>
</body>
</html>
八、 过滤器
在util中新建LoginFilter类,继承Filter类
LoginFilter.java
- 在override中的init中实现初始化过滤器
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init Filter");
}
- 在override中的doFilter中实现过滤方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//判断请求是否是 可以放过的某一个请求,或者在session中已经保存了登录状态的数据
//Login.jsp ,login请求 ,fail页面,session中持有了数据(在登陆成功的状态下存进去的)
HttpServletRequest req = (HttpServletRequest)servletRequest;
HttpServletResponse resp = (HttpServletResponse)servletResponse;
if(ignore(req) || req.getSession().getAttribute("username") != null){
filterChain.doFilter(req,resp);
}else {//跳转 重定向到登录页面
resp.sendRedirect("/login.jsp");//login.jsp
}
}
private boolean ignore(HttpServletRequest req){
String[] uris = {"login","login.jsp","fail.jsp","MyCSS.css","css","js"};
for (String u:uris) {
if(req.getRequestURI().endsWith(u)){
return true;
}
}
return false;
}
- 在override中的destroy中实现销毁过滤器
@Override
public void destroy() {
System.out.println("destroy Filter");
}
九、 监听器
在util中新建 MySessionListener类,继承HttpSessionListener类
MySessionListener.java
- 在override中的sessionCreated创建session
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session created!");
httpSessionEvent.getSession().setMaxInactiveInterval(5);
}
- 在override中的sessionDestroyed销毁session
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session distroyed");
}
完整代码如下
一、 工具包
properties配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
username=root
password=123456
DBUtils.java
public class DBUtils {
//1.定义需要的工具类对象(变量定义)
protected static Connection connection = null;
protected static PreparedStatement pps = null;//后续都是用预状态通道来实现
protected static ResultSet rs = null;//结果集
protected static int count = 0;//受影响的行数
//登录的用户名和密码
private static String username;
private static String password;
private static String url;
private static String driverName;
//Druid
private static DruidDataSource druidDataSource = new DruidDataSource();
//2.加载驱动
static {
//Druid
ResourceBundle bundle = ResourceBundle.getBundle("db");//参数只写属性文件名,不需要写后缀
//加载属性文件
driverName = bundle.getString("driver");
url = bundle.getString("url");
username = bundle.getString("username");
password = bundle.getString("password");
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setUrl(url);
druidDataSource.setDriverClassName(driverName);
}
//3.获得连接
protected static Connection getConnection() {
try {
connection = druidDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
//4.得到预状态通道
protected static PreparedStatement getPps(String sql) {
try {
getConnection();//insert into users values(?,?,?,?,)
pps = connection.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return pps;
}
//5.绑定参数,给占位符赋值,list中保存的是给占位符所赋的值
private static void setParams(List list) {
try {
if (list != null && list.size() > 0) {//集合中有内容
for (int i = 0; i < list.size(); i++) {
pps.setObject(i + 1, list.get(i));//赋值,位置从1开始所以为i+1
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//6.增删改
protected static int update(String sql, List list) {
try {
getPps(sql);//得到预状态通道
setParams(list);//绑定参数
count = pps.executeUpdate();//pps.executeUpdate()执行sql语句,返回受影响的行数
} catch (SQLException e) {
e.printStackTrace();
}
return count;//返回受影响的行数
}
//7.查询
protected static ResultSet query(String sql, List list) {
try {
getPps(sql);//得到预状态通道
setParams(list);//绑定参数
rs = pps.executeQuery();//pps.executeUpdate()执行sql语句,返回结果集
return rs;//返回结果集
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//8.关闭资源
protected static void closeAll() {
try {
if (rs != null) {
rs.close();
}
if (pps != null) {
pps.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
二、 对象
User.java
public class User {
private String username;
private String userpassword;
public User() {
}
public User(String username, String userpassword) {
this.username = username;
this.userpassword = userpassword;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpassword() {
return userpassword;
}
public void setUserpassword(String userpassword) {
this.userpassword = userpassword;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", userpassword='" + userpassword + '\'' +
'}';
}
}
三、 创建登录页面
Login.jsp
<%--
Created by IntelliJ IDEA.
User: ss
Date: 2021/9/27
Time: 20:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
<link rel="stylesheet" href="MyCSS.css">
<script>
function validateName(){
var name = document.getElementById("username").value;
var msg = document.getElementById("nameMsg");
var reg = /^[\u4E00-\u9FA5]{2,4}$/;
var res = reg.test(name);
if(name == null || name == ""){
msg.innerHTML = "用户名不能为空";
msg.style.color = "red";
return false;
}else if(res == false){
msg.innerHTML = "用户名格式错误";
msg.style.color = "red";
return false;
}
return true;
}
function validatePassword(){
var name = document.getElementById("password").value;
var msg = document.getElementById("passwordMsg");
if(name == null || name == ""){
msg.innerHTML = "密码不能为空";
msg.style.color = "red";
return false;
}
return true;
}
</script>
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div class="form">
<h2>用户登录</h2><br />
<!-- <form action="test" method="post"> -->
<form id="myForm" class="form-horizontal" role="form" action="/login" method="post">
<div>
<input id="username" class="inputStyle" name="username" type="text" placeholder="用户名" onblur="validateName()"/>
</div>
<span id="nameMsg"></span>
<div>
<input id="password" class="inputStyle" name="userpassword" type="password" placeholder="密码" onblur="validatePassword()"/>
</div>
<span id="passwordMsg"></span>
<div>
<input class="buttomStyle" type="submit" value="登录" />
</div>
</form>
</div>
</div>
</div>
</section>
</body>
</html>
MyCss.css
/**
* 显示水平居中
*/
section {
position: relative;
overflow: hidden;
display: flex; /*垂直居中对齐*/
justify-content: center;
align-items: center;
min-height: 100vh;
/* linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片 */
background: linear-gradient(to bottom, #f1f4f9, #dff1ff);
}
/* 背景颜色 */
.color {
/* 绝对定位 */
position: absolute;
/* 使用filter(滤镜) 属性,给图像设置高斯模糊*/
filter: blur(200px);
}
/* :nth-child(n) 选择器匹配父元素中的第 n 个子元素 */
.color:nth-child(1) {
top: -350px;
width: 600px;
height: 600px;
background:#FFC0CB;
}
.color:nth-child(2) {
bottom: -150px;
left: 100px;
width: 500px;
height: 500px;
background: #FFFFE0;
}
.color:nth-child(3) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background:#DDA0DD;
}
.color:nth-child(4) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background:#FFFFFF;
}
.box {
position: relative;
}
/* 登录框样式 */
.container {
position: relative;
width: 400px;
min-height: 400px;
background: rgba(255, 255, 255, 0.1);
display: flex;
justify-content: center;
align-items: center;
backdrop-filter: blur(5px);
box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.5);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
/* 输入框样式 */
.inputStyle{
width: 100%;
padding: 10px 20px;
margin-top: 20px;
background: rgba(255, 255, 255, 0.2);
outline: none;
border: none;
border-radius: 30px;
border: 1px solid rgba(255, 255, 255, 0.5);
border-right: 1px solid rgba(255, 255, 255, 0.2);
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
font-size: 16px;
letter-spacing: 1px;
color: #000;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}
/* 登录按钮样式 */
.buttomStyle{
width: 100%;
padding: 10px 20px;
max-width: 100px;
margin-top: 30px;
margin-left: 10px;
margin-bottom: 20px;
border-radius: 30px;
font-size: 16px;
letter-spacing: 1px;
background: #fff;
color: #666;
font-weight: 600;
cursor: pointer;
}
四、 web登录
接收客户端数据LoginServlet .java
@WebServlet("/login")//前端action与此对应
public class LoginServlet extends HttpServlet {
Dao dao = new Dao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
//取值
String username = req.getParameter("username");
System.out.println("用户输入的用户名:"+username);
String userpassword = req.getParameter("userpassword");
System.out.println("用户输入的密码:"+userpassword);
User user = dao.login(username,userpassword);
if( user != null){
System.out.println("登陆成功");
req.getSession().setAttribute("user",user);//登陆成功,session就有了一个凭证
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}else{
System.out.println("登录失败");
resp.sendRedirect("/fail.jsp");
//req.getRequestDispatcher("/fail.html").forward(req,resp);
}
}
}
退出后返回登录界面LogoutServlet.java
@WebServlet("/logOut")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
req.getSession().invalidate();
Enumeration em = req.getSession().getAttributeNames();
while(em.hasMoreElements()){
req.getSession().removeAttribute(em.nextElement().toString());
}
// //req.getRequestDispatcher("index.jsp").forward(req,resp);
resp.sendRedirect("/login.jsp");//login.jsp
}
}
五、 数据处理
Dao.java
public class Dao extends DBUtil {
public static User login(String username, String password){
System.out.println("进入check in");
String sql = "select* from user where username = ? and userpassword = ?";
ArrayList param = new ArrayList();
param.add(username);
param.add(password);
ResultSet query = query(sql, param);
try {
if(!query.next()){
System.out.println("dao:false");
return null;
}else{
User user = new User();
user.setUsername(query.getString("username"));
user.setUserpassword(query.getString("userpassword"));
System.out.println("dao:true");
return user;
}
} catch (SQLException throwables) {
System.out.println(throwables.getMessage());
return null;
}finally {
closeAll();
}
}
}
六、 登录结果页面
Success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>登陆成功</title>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="MyCSS.css">
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div>
<h2 style="color:#8B008B">欢迎登录!</h2>
<div style="margin-top: 50px ;margin-left: 90px" >
<a href="/logOut">点击退出登录</a>
</div>
</div>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
</div>
</div>
</section>
</body>
</html>
Fail.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>登录失败</title>
<script type="text/javascript" src="js/jquery-1.11.1.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link rel="stylesheet" href="css/bootstrap.css" />
<link rel="stylesheet" href="MyCSS.css">
<script>
//基本弹框
alert("用户名或密码错误,登录失败!");
</script>
</head>
<body>
<section>
<div class="box">
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="container">
<div>
<a href="/logOut">点击重新登录</a>
</div>
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="40"
aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
</div>
</div>
</div>
</div>
</section>
</body>
</html>
七、 过滤器
LoginFilter.java
/**
* 注册
*/
@WebFilter("*")
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init Filter");
}
/**
* 实现过滤的方法
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//判断请求是否是 可以放过的某一个请求,或者在session中已经保存了登录状态的数据
//Login.jsp ,login请求 ,fail页面,session中持有了数据(在登陆成功的状态下存进去的)
HttpServletRequest req = (HttpServletRequest)servletRequest;
HttpServletResponse resp = (HttpServletResponse)servletResponse;
if(ignore(req) || req.getSession().getAttribute("username") != null){
filterChain.doFilter(req,resp);
}else {//跳转 重定向到登录页面
resp.sendRedirect("/login.jsp");//login.jsp
}
}
private boolean ignore(HttpServletRequest req){
String[] uris = {"login","login.jsp","fail.jsp","MyCSS.css","css","js"};
for (String u:uris) {
if(req.getRequestURI().endsWith(u)){
return true;
}
}
return false;
}
@Override
public void destroy() {
System.out.println("destroy Filter");
}
}
八、 监听器
MySessionListener.java
public class MySessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session created!");
httpSessionEvent.getSession().setMaxInactiveInterval(5);
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session distroyed");
}
}