Servlet实现用户登录退出的功能
- 实现功能的概述
- 前端代码的编写
- 使用Servlet接收前端的请求
- 编写dao层,验证是否可以登录成功
实现功能的概述
需要给项目添加一个登录模块,要求贴切真实网站需求,页面有表单验证,后台连接数据库真实判断,跳转到不同页面给用户提示。登录成功后,将用户名存储在session中,在页面显示出用户名,点击退出登录后,直接返回的登录页面。
前端代码的编写
页面样式主要参考: 【html+css实现漂亮的透明登录页面,HTML实现炫酷登录页面】真的很好看。
将html页面改为jsp页面【<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>】,就是将这段代码放到html页面的最上面,然后将后缀改为jsp就好了。
登录页面:index.jsp 。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link href="css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
<section>
<!-- 背景颜色 -->
<div class="color"></div>
<div class="color"></div>
<div class="color"></div>
<div class="box">
<!-- 背景圆 -->
<div class="circle" style="--x:0"></div>
<div class="circle" style="--x:1"></div>
<div class="circle" style="--x:2"></div>
<div class="circle" style="--x:3"></div>
<div class="circle" style="--x:4"></div>
<!-- 登录框 -->
<div class="container">
<div class="form">
<h2>登录</h2>
<form action="login" method="post">
<div class="inputBox">
<input name="username" type="text" placeholder="账户" required autofocus>
</div>
<div class="inputBox">
<input name="password" type="password" placeholder="密码" required>
</div>
<div class="inputBox">
<input type="submit" value="登录">
</div>
<p class="forget">忘记密码?<a href="#">点击这里</a></p>
<p class="forget">没有账户?<a href="#">注册</a></p>
</form>
</div>
</div>
</div>
</section>
</body>
</html>
登录页面index.jsp的css样式代码:
/* 清除浏览器默认边距,
使边框和内边距的值包含在元素的width和height内 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 使用flex布局,让内容垂直和水平居中 */
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);
}
/* 背景颜色 */
section .color {
/* 绝对定位 */
position: absolute;
/* 使用filter(滤镜) 属性,给图像设置高斯模糊*/
filter: blur(200px);
}
/* :nth-child(n) 选择器匹配父元素中的第 n 个子元素 */
section .color:nth-child(1) {
top: -350px;
width: 600px;
height: 600px;
background: #ff359b;
}
section .color:nth-child(2) {
bottom: -150px;
left: 100px;
width: 500px;
height: 500px;
background: #fffd87;
}
section .color:nth-child(3) {
bottom: 50px;
right: 100px;
width: 500px;
height: 500px;
background: #00d2ff;
}
.box {
position: relative;
}
/* 背景圆样式 */
.box .circle {
position: absolute;
background: rgba(255, 255, 255, 0.1);
/* backdrop-filter属性为一个元素后面区域添加模糊效果 */
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);
border-radius: 50%;
/* 使用filter(滤镜) 属性,改变颜色。
hue-rotate(deg) 给图像应用色相旋转
calc() 函数用于动态计算长度值
var() 函数调用自定义的CSS属性值x*/
filter: hue-rotate(calc(var(--x) * 70deg));
/* 调用动画animate,需要10s完成动画,
linear表示动画从头到尾的速度是相同的,
infinite指定动画应该循环播放无限次*/
animation: animate 10s linear infinite;
/* 动态计算动画延迟几秒播放 */
animation-delay: calc(var(--x) * -1s);
}
/* 背景圆动画 */
@keyframes animate {
0%, 100%{
transform: translateY(-50px);
}
50% {
transform: translateY(50px);
}
}
.box .circle:nth-child(1) {
top: -50px;
right: -60px;
width: 100px;
height: 100px;
}
.box .circle:nth-child(2) {
top: 150px;
left: -100px;
width: 120px;
height: 120px;
z-index: 2;
}
.box .circle:nth-child(3) {
bottom: 50px;
right: -60px;
width: 80px;
height: 80px;
z-index: 2;
}
.box .circle:nth-child(4) {
bottom: -80px;
left: 100px;
width: 60px;
height: 60px;
}
.box .circle:nth-child(5) {
top: -80px;
left: 140px;
width: 60px;
height: 60px;
}
/* 登录框样式 */
.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);
}
.form {
position: relative;
width: 100%;
height: 100%;
padding: 50px;
}
/* 登录标题样式 */
.form h2 {
position: relative;
color: #fff;
font-size: 24px;
font-weight: 600;
letter-spacing: 5px;
margin-bottom: 30px;
cursor: pointer;
}
/* 登录标题的下划线样式 */
.form h2::before {
content: "";
position: absolute;
left: 0;
bottom: -10px;
width: 0px;
height: 3px;
background: #fff;
transition: 0.5s;
}
.form h2:hover:before {
width: 53px;
}
.form .inputBox {
width: 100%;
margin-top: 20px;
}
/* 输入框样式 */
.form .inputBox input {
width: 100%;
padding: 10px 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: #fff;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}
.form .inputBox input::placeholder {
color: #fff;
}
/* 登录按钮样式 */
.form .inputBox input[type="submit"] {
background: #fff;
color: #666;
max-width: 100px;
margin-bottom: 20px;
font-weight: 600;
cursor: pointer;
}
.forget {
margin-top: 6px;
color: #fff;
letter-spacing: 1px;
}
.forget a {
color: #fff;
font-weight: 600;
text-decoration: none;
}
success.html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%-- 在jsp页面获取存储在session中的用户名 --%>
<%
String userName = (String) request.getSession().getAttribute("userName");
%>
欢迎您,<%= userName%> <br/>
<a href="loginOut">退出</a>
</body>
</html>
使用Servlet接收前端的请求
在我的index.html页面采用的是 < form action=“login” method=“post” > 提交。
使用接收login请求采用的是注解的方式,不是在xml文件中配置。
//采用注解的方式接收请求login
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
//这两个方法是继承HttpServlet的
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
//根据表单提交过来的是post请求,所有使用post请求处理
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码格式为UTF-8,防止乱码
req.setCharacterEncoding("UTF-8");
//getParameter:接收参数
String userName = req.getParameter("userName");
String passWord = req.getParameter("passWord");
//输出查看是否接收到了两个参数,可以验证路径是否正确
System.out.println(userName);
System.out.println(passWord);
LoginDao loginDao = new LoginDao();
//3 调用dao将查询验证信息推送到数据库服务器上
//查询到了则返回的结果为1;没有则为0
int result = loginDao.login(userName,passWord);
System.out.println(result);
System.out.println("=========================================");
//4 调用响应对象,根据验证结果将不同资源文件地址写入到响应头,交给游览器
if (result == 1){ //用户存在
HttpSession session = req.getSession();
//登录成功
//将userName存储在session中
session.setAttribute("userName" , userName);
//登录成功,使用重定向到成功页面
resp.sendRedirect("success.jsp");
}else {
//登录失败,重定向失败页面(也可以重定向会登录页面 index.jsp)
resp.sendRedirect("loginError.jsp");
}
}
}
注意:如果接收的两个参数在控制台没有输入,则说明路径不正确
登录成功页面
点击退出,在success.jsp 页面,前端所请求的方法是loginOut ;< a href=“loginOut”>退出< /a>
@WebServlet(urlPatterns = "/loginOut")
public class LoginOutServlet extends HttpServlet {
//a标签所请求的方法是get
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
//使session失效
session.invalidate();
//重定向回登录页面
resp.sendRedirect("index.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
在登录的servlet中使用session存储了用户名,然后在退出的servlet中将session中的值清空了,即退出成功
编写dao层,验证是否可以登录成功
先编写一个连接数据库的工具类:
public class JdbcUtil {
final String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
final String userName = "root";
final String password = "123456";
PreparedStatement ps = null;
Connection con = null;
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//封装连接通道创建细节
public Connection getCon(){
try {
con = DriverManager.getConnection(url,userName,password);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
public PreparedStatement createStatement(String sql){
try {
ps = getCon().prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return ps;
}
public void close(){
if (ps != null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public void close(ResultSet rs){
if (rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
dao层的代码:
public class LoginDao extends JDBCUtill {
/**
* 判断数据库中是否有用户输入的账号和密码
*/
JdbcUtil util = new JdbcUtil();
//登录验证
public int login(String userName,String password){
String sql = "select count(*) from user where userName=? and passWord=?";
PreparedStatement ps = util.createStatement(sql);
ResultSet rs = null;
int result = 0;
try {
ps.setString(1,userName);
ps.setString(2,password);
rs = ps.executeQuery();
while (rs.next()){
result = rs.getInt("count(*)");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
util.close(rs);
}
return result;
}
}
以上就是我的登录退出的代码,如果有问题可以提出评论。
最后,如果有问题,希望指正,一起进步。