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");
        }
	}

}

注意:如果接收的两个参数在控制台没有输入,则说明路径不正确

登录成功页面

java退出登录怎么清除cookie javaweb退出登录代码_java退出登录怎么清除cookie


点击退出,在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;
        }
}

以上就是我的登录退出的代码,如果有问题可以提出评论。

最后,如果有问题,希望指正,一起进步。