过滤Filter、监听listener 登录 注册 强制下线

                                           目录

要求:

一.图片展示

1.登录界面

2.注册界面

3.查询用户登录信息界面

​二.主要的jsp代码

         1.登录---login.jsp

         2.注册--register.jsp

         3.用户登录信息查询---userLoginMsg.jsp

三.主要的java代码

1.工具类 Utils 层

a.Druid工具类的封装

b. UUID工具的封装

2.  dao层

3.servlet层

a.  登录

b.注册

4.service层

5.listener层     --------   用于监听登录次数 、 时间

6.filter层 ----用于过滤 

a.过滤   异地登录  强制下线

b.过滤登录  ---  未登录状态  --- 点击后重定向到登录界面

7.entity层   

a.封装用户登录信息    类

b.  用户   类


要求:

使用maven的方式,创建web项目完成如下功能:

1 编辑登陆页面

2 模拟登陆功能(可以使用数据库 也可以不用,模拟即可)

3 登陆成功之后将 用户登陆成功的状态保存在session中

4 使用其他浏览器再次登陆,登陆成功之后,将其他地方登陆该用户强制下线

5 编辑主页

6 添加过滤器 ,控制如果用户未登录则无法访问主页,必须登陆之后才能访问

7 添加监听器, 记录用户登陆信息 例如:时间 次数等等

一.图片展示

1.登录界面

2.注册界面

3.查询用户登录信息界面

二.主要的jsp代码

1.登录---login.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录界面</title>
</head>
<body>
<a href="index.jsp">返回测试♥网页界面</a>
    <form action="login" method="post">
        <p>用户名:<input type="text" name="username" placeholder="请输入用户名"></p>
        <p>密&nbsp&nbsp&nbsp&nbsp码:<input type="text" name="password" placeholder="请输入密码"></p>
        <p>
        <input type="submit" value="登录">
        <span style="color: red">
            ${empty error ? "" : error}
        </span>
        </p>
    </form>
    <p>没有账户?<a href="register.jsp">点此注册</a></p>
</body>
</html>

2.注册--register.jsp



<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册♥界面</title>
</head>
<body>
<a href="index.jsp">返回测试♥网页界面</a>
    <form action="register" method="post">
        <p>
            用户名:<input type="text" name="username">
            <span style="color: red">
                ${empty error? "" : error}
            </span>
        </p>
        <p> 密★码:<input type="text" name="password"></p>
        <p> 生★日:<input type="date" name="birthday"></p>
        <p> 电★话:<input type="text" name="telephone"></p>
        <p>
            <input type="reset" value="重置">
            <input type="submit" value="注册">
        </p>
    </form>

</body>
</html>

3.用户登录信息查询---userLoginMsg.jsp

<%@ page import="java.util.Map" %>
<%@ page import="com.ak.entity.UserLoginMsg" %>
<%@ page import="java.util.Set" %>
<%@ page import="java.util.Iterator" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>统计所有用户的登录信息</title>
</head>
<body>
<%
    Map<String, UserLoginMsg> userLoginMsgMap = (Map<String, UserLoginMsg>) application.getAttribute("userLoginMsgMap");
    Set<Map.Entry<String, UserLoginMsg>> entries = userLoginMsgMap.entrySet();
    Iterator<Map.Entry<String, UserLoginMsg>> iterator = entries.iterator();
    out.println("<table border='1' width='500px'><caption>统计所有用户的登录信息如下:</caption><tr><th>用户名</th><th>登录时间  </th><th>登录次数</th></tr>");
    while (iterator.hasNext()) {
        Map.Entry<String, UserLoginMsg> next = iterator.next();
        UserLoginMsg userLoginMsgValue = next.getValue();
        String username = userLoginMsgValue.getUsername();
        String loginTime = userLoginMsgValue.getLoginTime();
        int loginCount = userLoginMsgValue.getLoginCount();
        out.println("<tr style=\"text-align: center\"><td>" + username + "</td><td>" + loginTime + "</td><td>" + loginCount + "</td></tr>");
    }
    out.println("</table>");
    out.flush();
    
    out.close();
%>
</body>
</html>

三.主要的java代码

1.工具类 Utils 层

a.Druid工具类的封装

package com.ak.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DruidUtils {
    //定义成员变量  数据源
    private static DataSource dataSource;
    //使用静态代码块  读取配置文件信息
    static {
        try {
            //创建Properties 对象
            Properties p = new Properties();
            //基于反射技术  获取类加载器
            InputStream inputStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            p.load(inputStream);
            dataSource = DruidDataSourceFactory.createDataSource(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static DataSource getDataSource() {
        return dataSource;
    }

    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    public void close(Connection connection, Statement statement){
        if (connection != null && statement != null){
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public void close(Connection connection, Statement statement, ResultSet resultSet){
        if (connection != null && statement != null && resultSet != null){
            try {
                resultSet.close();
                statement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

b. UUID工具的封装

package com.ak.utils;

import java.util.UUID;

public class UUIDUtils {
    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-","");
    }
}

2.  dao层

package com.ak.dao;

import com.ak.entity.User;
import com.ak.utils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

public class UserDao {
    private QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());

    //注册用户  即添加用户
    public void registerUser(User user) {
        try {
            String sql = "insert into user values (?,?,?,?,?)";
            qr.update(sql, user.getId(), user.getUsername(), user.getPassword(), user.getBirthday(), user.getTelephone());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    //定义登录功能
    public User loginUser(User user) {
        User loginUser = null;
        try {
            String sql = "select * from user where username = ? and password = ?";
            loginUser = qr.query(sql, new BeanHandler<>(User.class), user.getUsername(), user.getPassword());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return loginUser;
    }

    public User findUserByName(String username) {
        try {
            String sql = "select*from user where username=?";
            User user = qr.query(sql, new BeanHandler<>(User.class), username);
            return user;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

3.servlet层

 a.  登录

package com.ak.filter;


import com.ak.entity.User;
import com.ak.service.UserService;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebFilter(filterName = "loginFilter", urlPatterns = "/login")
public class LoginFilter implements Filter {

    //声明成员变量
    private ServletContext servletContext = null;

    /**
     * 构造方法执行后  执行初始化
     *
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //获取servletContext对象
        servletContext = filterConfig.getServletContext();
        //准备一个map 用于保存 用户名和sessionID  并将map绑定在servletContext
        Map<String, String> userLoginMap = new HashMap<>();
        servletContext.setAttribute("userLoginMap", userLoginMap);
    }

    /**
     * 定义拦截到请求后  具体执行逻辑
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1.获取用户名
        servletRequest.setCharacterEncoding("utf-8");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //使用UserService  验证用户名和密码的正确性
        UserService userService = new UserService();
        User user = userService.loginUser(username, password);
        if (user != null) {
            //2.检查userLoginMap  中是否存在key = username
            Map<String, String> userLoginMap = (Map<String, String>) servletContext.getAttribute("userLoginMap");
            if (userLoginMap.containsKey(username)) {
                //3.如果存在  已登录userLoginMap
                //   a.获取userLoginMap 中  username  对应的sessionID    sid01
                String sid01 = userLoginMap.get(username);
                System.out.println("sid01=" + sid01);
                //   b.获取当前的sessionID   sid02
                String sid02 = request.getSession().getId();
                System.out.println("sid02=" + sid02);
                //   c.如果sid01 != sid02  异地登陆   则  将userLoginMap.put(username,sid02)
                if (!sid01.equals(sid02)) {
                    userLoginMap.put(username, sid02);
                }
            } else {
                //4.如果不存在   则第一次登陆  获取sessionID 与 username  存在  userLoginMap
                userLoginMap.put(username, request.getSession().getId());
            }
        }
        //5.放行
        filterChain.doFilter(servletRequest, servletResponse);
    }


    @Override
    public void destroy() {
        System.out.println("Filter销毁执行了......");

    }
}

b.注册

package com.ak.servlet;

import com.ak.entity.User;
import com.ak.service.UserService;

import javax.servlet.RequestDispatcher;
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 java.io.IOException;

@WebServlet(name = "registerServlet",urlPatterns = "/register")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        User user = new User();
        String username = req.getParameter("username");
        user.setUsername(username);
        String password = req.getParameter("password");
        user.setPassword(password);
        String birthday = req.getParameter("birthday");
        user.setBirthday(birthday);
        String telephone = req.getParameter("telephone");
        user.setTelephone(telephone);
        UserService userService = new UserService();
        String str = userService.registerUser(user);
        if (str.equals("success")){
            System.out.println("servlet层,提示:"+"Registered successfully");
            //重定向到登录界面
            resp.sendRedirect("login.jsp");
        } else if (str.equals("msg")){
            req.setCharacterEncoding("utf-8");
            //返回提示信息
            req.setAttribute("error","用户名已存在!");
            //获取转发器  并指定转发路径
            RequestDispatcher requestDispatcher = req.getRequestDispatcher("register.jsp");
            //执行转发
            requestDispatcher.forward(req,resp);
        } else {
            req.setCharacterEncoding("utf-8");
            //返回提示信息
            req.setAttribute("error","用户名和密码不能为空!");
            //获取转发器  并指定转发路径
            RequestDispatcher requestDispatcher = req.getRequestDispatcher("register.jsp");
            //执行转发
            requestDispatcher.forward(req,resp);
        }
    }
}

4.service层

package com.ak.service;

import com.ak.dao.UserDao;
import com.ak.entity.User;
import com.ak.utils.UUIDUtils;

/**
 * 负责业务逻辑处理
 */
public class UserService {
    private UserDao userDao = new UserDao();

    //登录
    public User loginUser(String username, String password) {
        //将username  和 password  封装成一个user对象
        //调用UserDao  中的 longingUser 方法
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        System.out.println("service层,User:" + user);
        User loginUser = userDao.loginUser(user);
        return loginUser;
    }

    //注册
    public String registerUser(User user) {
        if (!user.getUsername().equals("") && !user.getPassword().equals("")) {
            User userByName = userDao.findUserByName(user.getUsername());
            if (userByName == null) {
                user.setId(UUIDUtils.getUUID());
                userDao.registerUser(user);
                return "success";
            } else {
                return "msg";
            }
        } else {
            return "error";
        }
    }
}

5.listener层     --------   用于监听登录次数 、 时间

package com.ak.listener;


import com.ak.entity.UserLoginMsg;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@WebListener
public class UserLoginListener implements HttpSessionAttributeListener, ServletContextListener {
    /**
     * 1.在ServletContext中,绑定一个userLoginMsgMap  用于记录所有用户的登录
     *     userLoginMsgMap  key:username
     *                      value : 登录时间 + 登录次数   封装一个javaBean
     * 2.监听session中属性为username的变化,有变化,将其放入userLoginMsgMap
     *
     */
    //声明servletContext的引用
    private ServletContext servletContext = null;

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //在项目启动的时候   初始化 servletContext
        servletContext = servletContextEvent.getServletContext();
        //用于记录用户登录信息的Map
        Map<String, UserLoginMsg> userLoginMsgMap = new HashMap<>();
       //绑定到servletContext
        servletContext.setAttribute("userLoginMsgMap",userLoginMsgMap);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        //销毁
        servletContext = null;
    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        System.out.println("session新增了属性:"+event.getName()+"="+event.getValue());
        addOrReplaceAction(event);
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {

    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
        System.out.println("session修改了属性:"+event.getName());
        addOrReplaceAction(event);
    }
    //封装  属性  新增和修改的逻辑
    public void addOrReplaceAction(HttpSessionBindingEvent event){
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        //1.判断新增属性名  是否是username
        if (event.getName().equals("username")){
            //获取用户名
            String username = (String) event.getSession().getAttribute("username");
            Map<String, UserLoginMsg> userLoginMsgMap = (Map<String, UserLoginMsg>)servletContext.getAttribute("userLoginMsgMap");
            //检测userLoginMsgMap中是否包含 key 为username的元素
            if (userLoginMsgMap.containsKey(username)){
                //如果包含  证明  不是第一次登录  获取UserLoginMsg  并修改登录时间
                UserLoginMsg userLoginMsg = userLoginMsgMap.get(username);
                //登录次数+1
                userLoginMsg.setLoginCount(userLoginMsg.getLoginCount()+1);
                //修改登录时间
                userLoginMsg.setLoginTime(date);
            } else {
                //不包含  证明  第一次登录
                UserLoginMsg userLoginMsg = new UserLoginMsg(username, date, 1);
                userLoginMsgMap.put(username,userLoginMsg);
            }
        }
    }
}

6.filter层 ----用于过滤 

a.过滤   异地登录  强制下线

package com.ak.filter;


import com.ak.entity.User;
import com.ak.service.UserService;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebFilter(filterName = "loginFilter", urlPatterns = "/login")
public class LoginFilter implements Filter {

    //声明成员变量
    private ServletContext servletContext = null;

    /**
     * 构造方法执行后  执行初始化
     *
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //获取servletContext对象
        servletContext = filterConfig.getServletContext();
        //准备一个map 用于保存 用户名和sessionID  并将map绑定在servletContext
        Map<String, String> userLoginMap = new HashMap<>();
        servletContext.setAttribute("userLoginMap", userLoginMap);
    }

    /**
     * 定义拦截到请求后  具体执行逻辑
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1.获取用户名
        servletRequest.setCharacterEncoding("utf-8");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //使用UserService  验证用户名和密码的正确性
        UserService userService = new UserService();
        User user = userService.loginUser(username, password);
        if (user != null) {
            //2.检查userLoginMap  中是否存在key = username
            Map<String, String> userLoginMap = (Map<String, String>) servletContext.getAttribute("userLoginMap");
            if (userLoginMap.containsKey(username)) {
                //3.如果存在  已登录userLoginMap
                //   a.获取userLoginMap 中  username  对应的sessionID    sid01
                String sid01 = userLoginMap.get(username);
                System.out.println("sid01=" + sid01);
                //   b.获取当前的sessionID   sid02
                String sid02 = request.getSession().getId();
                System.out.println("sid02=" + sid02);
                //   c.如果sid01 != sid02  异地登陆   则  将userLoginMap.put(username,sid02)
                if (!sid01.equals(sid02)) {
                    userLoginMap.put(username, sid02);
                }
            } else {
                //4.如果不存在   则第一次登陆  获取sessionID 与 username  存在  userLoginMap
                userLoginMap.put(username, request.getSession().getId());
            }
        }
        //5.放行
        filterChain.doFilter(servletRequest, servletResponse);
    }


    @Override
    public void destroy() {
        System.out.println("Filter销毁执行了......");

    }
}

b.过滤登录  ---  未登录状态  --- 点击后重定向到登录界面

package com.ak.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

@WebFilter(filterName = "loginFilter2",urlPatterns = "/*")
public class LoginFilter2 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter初始化执行了......");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //1.判断请求路径是否 是  index.jsp
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //获取请求路径
        String servletPath = request.getServletPath();
        if (servletPath.contains("index")){
            //2.是  访问index.jsp 再判断登录状态
            HttpSession session = request.getSession();
            String username = (String) session.getAttribute("username");
            ServletContext servletContext = request.getServletContext();
            Map<String,String> userLoginMap = (Map<String,String>)servletContext.getAttribute("userLoginMap");
            //获取登录成功之后,保存的sessionID
            String sid01 = userLoginMap.get(username);
            //获取本次登录的sessionID
            String sid02 = session.getId();
            if (username != null && sid02.equals(sid01)){
                //b.  已登录   放行
                filterChain.doFilter(request,servletResponse);
            } else {
                //a.  未登录   重定向到登录界面
                ((HttpServletResponse)servletResponse).sendRedirect("login.jsp");
            }
        } else {
            //3.不是  访问index.jsp 放行即可
            filterChain.doFilter(request,servletResponse);
        }

    }

    @Override
    public void destroy() {
        System.out.println("Filter销毁执行了......");
    }
}

7.entity层   

a.封装用户登录信息    类

package com.ak.entity;


public class UserLoginMsg {
    private String username;
    private String loginTime;
    private int loginCount;

    public UserLoginMsg() {
    }

    public UserLoginMsg(String username, String loginTime, int loginCount) {
        this.username = username;
        this.loginTime = loginTime;
        this.loginCount = loginCount;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getLoginTime() {
        return loginTime;
    }

    public void setLoginTime(String loginTime) {
        this.loginTime = loginTime;
    }

    public int getLoginCount() {
        return loginCount;
    }

    public void setLoginCount(int loginCount) {
        this.loginCount = loginCount;
    }

    @Override
    public String toString() {
        return "UserLoginMsg{" +
                "username='" + username + '\'' +
                ", loginTime='" + loginTime + '\'' +
                ", loginCount=" + loginCount +
                '}';
    }
}

b.  用户   类

package com.ak.entity;

public class User {
    private String id;
    private String username;
    private String password;
    private String birthday;
    private String telephone;

    public User() {
    }

    public User(String id, String username, String password, String birthday, String telephone) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.birthday = birthday;
        this.telephone = telephone;
    }

    public String getId() {
        return id;
    }

    public void setId(String 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;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", birthday='" + birthday + '\'' +
                ", telephone='" + telephone + '\'' +
                '}';
    }
}

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值