Java使用监听器实现在线统计、登录统计、登录人员记录等功能(HttpSessionAttributeListener 、 HttpSessionListener)

一、简介(使用的Java监听器)

1、使用HttpSessionAttributeListener , HttpSessionListener 来显示的在线统计和计数功能。使用的 springboot框架!
2、使用ServletContext容器,对在线统计、登录统计、登录信息进行存储。
3、确保了只有一个账号是登录状态,其他电脑登录,会将当前登出。
4、确保一台计算机只能同时登录一个账号。登录其他person,会将当前的person登出。

二、自定义的控制层(controller层)

1、person登录
    @ApiOperation(value = "person登录!")
    @PostMapping(value = "/loginPerson")
    public Result<Person> loginPerson(String username , String password , HttpSession session){
		//判断用户是否正确!
        Result<Person> result = personService.selectByUsername(username.trim());
        Person person = result.getData();
        if(person != null){
            Person inP = new Person();
            inP.setPersonId(person.getPersonId());
            inP.setUsername(username.trim());
            inP.setPassword(password.trim());
            Person outP = EncryptUserUtil.encryPerson(inP);
            if(!outP.getPassword().equals(person.getPassword())){
                return new Result("-1","密码错误!");
            }
        }else {
            return new Result("-1","该用户名不存在!");
        }
        //如果改session中已经绑定person信息,那么删除这个。
        ConcurrentHashMap<String , HttpSession> personL = (ConcurrentHashMap<String , HttpSession>)session.getServletContext().getAttribute("personL");
        Person pe =  (Person) session.getAttribute("person");
        if(pe != null){
            if(personL != null && personL.containsKey(pe.getUsername().trim())){
                //peronsL中移除改person及其对应的session信息。
                personL.remove(pe.getUsername().trim());
                //更新容器。
                session.getServletContext().setAttribute("personL" , personL);
                System.out.println(pe.getUsername() + ":out!");
            }
            session.removeAttribute("person");
        }
        //如果改username已经在其他地方登录,那么销毁该username的session数据。(换机器登录了)
        if(personL != null && personL.containsKey(username.trim())){
            //从personL中拿到username对应的session数据,并且销毁!
            //注意:personL数据的更新在销毁线程的函数中。
            personL.get(username.trim()).invalidate();
            System.out.println(username.trim() + ":out!");
        }
        //获取登录人数!
        Integer count = (Integer)session.getServletContext().getAttribute("login");
        //对登录人数进行限制,下为测试,限制三人。
        if(count!= null && count>= 3){
            return new Result<>("-5","登录人数已满,请耐心等候,或者刷新登录");
        }
        //如果personL是空的。那么创建该map。
        if(personL == null){
            personL = new ConcurrentHashMap<String , HttpSession>();
        }
        //将当前session与当前的person进行绑定。在监听器中,更新personL数据。
        session.setAttribute("person" , person);
        return new Result<Person>(person);
        }
2、person退出。
   @ApiOperation(value = "用户退出登录。")
    @GetMapping("/lostPerson")
    public Result lostPerson(HttpSession session){
        Person person = (Person)session.getAttribute("person");
        if(person != null){
            HashMap<String , HttpSession> personL = (HashMap<String , HttpSession>)session.getServletContext().getAttribute("personL");
            if(personL != null && personL.containsKey(person.getUsername().trim())){
                personL.remove(person.getUsername().trim());
                session.getServletContext().setAttribute("personL" , personL);
            }
            session.removeAttribute("person");
        }
        return new Result();
    }

三、自定义的监听器

package com.cc.listener;

import com.cc.model.Person;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ServletContext;
import javax.servlet.http.*;
import java.util.concurrent.ConcurrentHashMap;
/*
 * 关于HttpSessionAttributeListener的总结
 * 1、attributeAdded 方法,是在session添加setAttribute时被触发!
 * 2、attributeRemoved方法,是在session移除removeAttribute后被触发。注意是属性已经移除后,才被触发!不能获取相关属性。
 * 3、sessionCreated方法,是在session被创建的时候被触发。
 * 4、sessionDestroyed方法,是在session被销毁的时候被触发。在改方法中可以获取设置的相关属性。
 * 5、sessionDestroyed方法执行:先执行改方法,再执行attributeRemoved方法;
*/
@Data
@Slf4j
public class MyLoginListener implements HttpSessionAttributeListener , HttpSessionListener {

	//在线计数
    private static int activeSessions = 0;
    //登录人员计数
    private static int activeLoginSessions = 0;
    //存放person的username和登录对应的session!
    private static ConcurrentHashMap<String , HttpSession> personL;
    /**
     * controller中session.setAttribute("person" , person)的时候触发!-代表person登录。
     * @param se
     */
    public void attributeAdded(HttpSessionBindingEvent se) {
    	//获取session.setAttribute("person" , person)中的 “person”
        String name = se.getName();
        //如果是person登录
        if("person".equalsIgnoreCase(name)){
            HttpSession session = se.getSession();
            Person person = (Person)session.getAttribute("person");
            //获取容器
            ServletContext app = session.getServletContext();
            //容器中获取所有person的登录信息。
            personL = (ConcurrentHashMap<String , HttpSession>)app.getAttribute("personL");
            if(personL == null){
            	//如果容器中没有,那么初始化一个personL.
                personL = new ConcurrentHashMap<String , HttpSession>();
            }
            //将当前用户放入到personL中。
            personL.put(person.getUsername() , session);
            //登录计数添加。
            activeLoginSessions++;
            //将登录计数,和person对应的session的map数据放入到app容器中。
            app.setAttribute("login" , activeLoginSessions);
            app.setAttribute("personL" , personL);
            System.out.println(person.getUsername() + ":login!");
        }
    }

    /**
     * 某个person用户退出session.removeAttribute("person")的时候触发!
     * @param se
     */
    public void attributeRemoved(HttpSessionBindingEvent se) {
        System.out.println("------------测试销毁调用!-----------");
        String name = se.getName();
        //把session.removeAttribute("person")定义为退出登录。
        if("person".equalsIgnoreCase(name)){
            HttpSession session = se.getSession();
            ServletContext app = session.getServletContext();
            //登录计数减少!
            if(activeLoginSessions > 0){
                activeLoginSessions--;
            }
            //重新写入到容器中。
            app.setAttribute("login" , activeLoginSessions);
            System.out.println("----outPerson----");
            /*app.setAttribute("personL" , personL);*/
        }
    }
	
    public void attributeReplaced(HttpSessionBindingEvent se) {
    }
	 /**
     * session创建的时候触发!
     * @param se
     */
    public void sessionCreated(HttpSessionEvent se){
        //在线计数加一。
        activeSessions++;
        //后去容器。
        ServletContext servletContext = se.getSession().getServletContext();
        //将在线计数写入容器中。
        servletContext.setAttribute("online" , activeSessions);
        /*System.out.println("----create----" + personL);*/
    }
	 /**
     * session销毁的时候触发!
     * 注意:这里不需要登录计数减一,经过实测,再执行sessionDestroyed方法后,会自动执行attributeRemoved方法
     * @param se
     */
    public void sessionDestroyed(HttpSessionEvent se) {
    	//在线计数减一。
        if(activeSessions > 0){
            activeSessions--;
        }
        //在线计数更新到容器中
        ServletContext servletContext = se.getSession().getServletContext();
        servletContext.setAttribute("online" , activeSessions);
        //获取销毁的session。
        HttpSession session = se.getSession();
        //如果改session中含person,说明是person登录的session。
        Person person = (Person)session.getAttribute("person");
        if(person != null ){
			//在容器中获取person的信息map数据。
            personL = (ConcurrentHashMap<String , HttpSession>)servletContext.getAttribute("personL");
            if(personL != null){
            	//如果personL数据存在,那么将personL中对应的perosn登录session信息移除!
                personL.remove(person.getUsername());
            }else {
                personL = new ConcurrentHashMap<String , HttpSession>();
            }
            //更新容器中的personL。
            servletContext.setAttribute("personL" , personL);

        }
        System.out.println("--------destroy session--------:" + person);
    }
}

四、监听器注入web容器中

@Configuration
@Data
public class MyLoginLisConfig {

    final MyLoginListener myLoginListener;

    public MyLoginLisConfig (){
        this.myLoginListener = new MyLoginListener();
    }

    @Bean
    public ServletListenerRegistrationBean<MyLoginListener> listenerRegistrationBean() {
        ServletListenerRegistrationBean<MyLoginListener> registrationBean = new ServletListenerRegistrationBean<>();
        registrationBean.setListener(myLoginListener);
        return registrationBean;
    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值