springboot project listener does not work

1. Use springboot project, now there is a demand in add or modify a menu, the menu will affect the roles, roles affect users. All affected users want to log in again.

Own ideas realized is this: write a listener, upon receipt of a specific request, to listen to all of the current user, if the user is affected, the destruction of session, so that log in again.

 

  Once you have the idea, the beginning of Internet search is how to add the listener in spring boot in: Most ideas online are the same: use @ServletComponentScan and a realization HttpSessionListener approach it. (Reference: https://www.cnblogs.com/liuyong1993/p/10012808.html ). But after their own According to this configuration, and has been ineffective. When can start to debug the custom of listening inside, but can not be achieved after logging missing

sessionCreated()
package com.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * session监听器
 * @author Administrator
 */
@WebListener
public class SessionListener implements HttpSessionListener{

    private int onlineCount = 0;//记录session的数量
    
    /**
     * session创建后执行
     */
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        onlineCount++;
        System.out.println("【HttpSessionListener监听器】 sessionCreated, onlineCount:" + onlineCount);
        se.getSession().getServletContext().setAttribute("onlineCount", onlineCount);
    }

    /**
     * session失效后执行
     */
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        if (onlineCount > 0) {
            onlineCount--;
        }
        System.out.println("【HttpSessionListener监听器】 sessionDestroyed, onlineCount:" + onlineCount);
        se.getSession().getServletContext().setAttribute("onlineCount", onlineCount);
    }

}
复制代码

  

The group also asked the help of the great God looked down, there is no problem. At first suspect is not logged when listening HttpSession, because implementation is HttpSessionListener, there is a need to initiate the action, but they also have their own login httpSession. Then tested in their own inside the test class, found sesionId exist:

package com.sq.transportmanage.gateway.api.auth;

import com.alibaba.fastjson.JSONObject;
import com.sq.transportmanage.gateway.api.web.interceptor.AjaxResponse;
import com.sq.transportmanage.gateway.api.web.interceptor.LoginoutListener;
import com.sq.transportmanage.gateway.service.common.shiro.session.RedisSessionDAO;
import com.sq.transportmanage.gateway.service.common.web.RestErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @Author fanht
 * @Description
 * @Date 2020/3/5 下午6:46
 * @Version 1.0
 */
@RestController
@RequestMapping("/loginoutController")
public class LoginoutController extends RedisSessionDAO{

    private Logger logger = LoggerFactory.getLogger(this.getClass());



    @RequestMapping("/userLoginOut")
    @ResponseBody
    public AjaxResponse userLoginOut(String userIds, HttpSession httpSession,
                                     HttpServletRequest request){

        logger.info("httpSessionId" + httpSession.getId() + ",是否是session会话:" +
        request.getSession (false)); 
        the HttpSession request.getSession the session = (); 
        String loginName = (String) session.getAttribute ( "loginName"); 
        logger.info ( "loginName:" + loginName); 
        logger.info ( "call cache and clear shiro Interface exit "+ userIds); 
        logger.info (" access to information accessed listening "+ JSONObject.toJSONString (LoginoutListener.sessionCount)); 
        the try { 
            String the userId [] = StringUtils.tokenizeToStringArray (userIds,", " ); 
            for(int i = 0;i<userId.length;i++){
                clearRelativeSession(null,null,Integer.valueOf(userId[i]));
            }
            return AjaxResponse.success (null); 
        } the catch (a NumberFormatException E) { 
            e.printStackTrace (); 
            logger.error ( "exit abnormal Shiro" + E); 
            return AjaxResponse.fail(RestErrorCode.UNKNOWN_ERROR);
        }
    }

    @Override
    public void clearRelativeSession(Integer permissionId, Integer roleId, Integer userId) {
        super.clearRelativeSession(null, null, userId);
    }
}

  Is able to print sessionId, that there is no session is empty.

 

Then think of our projects which use the shiro, it will not be shiro rewrite the session mechanism? Think of this question, and search the Internet. Finally, this discovery is possible (Reference: https://blog.csdn.net/qq_34021712/article/details/80418112 )

Attach your own configuration:

 Custom shiroSessionListener:

 

com.sq.transportmanage.gateway.api.web.interceptor Package; 

Import com.google.common.collect.Maps; 
Import com.sq.transportmanage.gateway.service.common.shiro.session.RedisSessionDAO; 
Import the org.apache. shiro.session.Session; 
Import org.apache.shiro.session.SessionListener; 
Import org.slf4j.Logger; 
Import org.slf4j.LoggerFactory; 
Import a java.util.Map; 
Import java.util.concurrent.atomic.AtomicInteger; 

/ ** 
 * @author fanht 
 * @Description monitor what users currently, when the specific notification is received notice Log 
 * @Date 2020/3/5 1:48 pm 
 * @Version 1.0 
 * / 
// @ WebListener 
public class the extends LoginoutListener RedisSessionDAO implements SessionListener {

    Logger Logger = LoggerFactory.getLogger Private (this.getClass ()); 
    public static Final the Map <Long, String> mapuser Maps.newHashMap = (); 
    public static Final sessionCount of AtomicInteger of AtomicInteger new new = (0); 

    @Override 
    public void the onStart ( the session the session) { 
        // create a session, plus a number of online 
        logger.info ( "======" + sessionCount); 
        sessionCount.incrementAndGet (); 
    } 

    @Override 
    public void onStop (the session the session) { 
        // session exit , line number minus one 
        sessionCount.decrementAndGet (); 
    } 

    @Override 
    public void onExpiration (the Session the session) {  
        // the session expires, the number of line minus one
        sessionCount.decrementAndGet (); 

    }


    /**
     * 获取在线人数使用
     * @return
     */
    public AtomicInteger getSessionCount() {
        return sessionCount;
    }



    /*@Override
    public void sessionCreated(HttpSessionEvent se) {
        onlineCount++;
        logger.info("创建start====== ===" + se.getSession().getId());
        mapUser.put(se.getSession().getCreationTime(),se.getSession().getId());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        logger.info("销毁session=============");
    }*/
}

  

ShiroConfiguration which added to monitor configuration:
 @Bean("sessionManager")
    public DefaultWebSessionManager sessionManager(RedisSessionDAO sessionDAO, SimpleCookie sessionIdCookie) {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        //session存活时间60分钟
        sessionManager.setGlobalSessionTimeout(3600000);
        sessionManager.setDeleteInvalidSessions(true);
        //自定义监听 fht 不能使用@WebListern的 HttpSessionListerner 因为shiro重写了session 2020-03-05
        Collection<SessionListener> sessionListeners = new ArrayList<>();
        sessionListeners.add(sessionListener());
        sessionManager.setSessionListeners(sessionListeners);
        //sessionManager.setSessionValidationSchedulerEnabled(true);
        //sessionManager.setSessionValidationScheduler(sessionValidationScheduler);
        sessionManager.setSessionDAO(sessionDAO);
        sessionManager.setSessionIdCookieEnabled(true);
        sessionManager.setSessionIdCookie(sessionIdCookie);
        return sessionManager;
    }

  

/**
     * 自定义shiro监听
     * @return
     */
    @Bean("sessionListener")
    public LoginoutListener sessionListener(){
        LoginoutListener loginoutListener = new LoginoutListener();

        return loginoutListener;
    }

  

 

Then restart, test and found to shiro can enter custom monitor inside. . . .

 

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/thinkingandworkinghard/p/12423913.html