【JavaWeb】基于 JSP、EL表达式实现登录,并使用过滤器与监听器


任务概述

前面我们实现了用户登录功能,当时我们要求用户登录成功后,跳转到success.html 页面
【相关博文:Html、Servlet、JDBC实现页面登录】

现在需要做需求迭代:
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基础知识


任务过程

  1. 创建数据库,保存用户名和密码

  2. 创建登录页面,要求用户输入用户名和密码

  3. 接收用户提交的用户名和密码,接收后将数据传递到数据库进行验证

  4. 根据验证结果,跳转到不同的结果页面(成功跳转到 success.html、失败
    跳转到 false.html)

  5. 实现对文件的过滤

  6. 实现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

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

猜你喜欢

转载自blog.csdn.net/m0_50609545/article/details/120617775