springboot集成拦截器,过滤器,监听器 (拦截器和reids实现单设备登录)

springboot官方文档

本项目地址

项目目录

│ pom.xml
└─src
    └─main
        ├─java
        │  └─com
        │      └─base
        │          │  Application.java # 启动类
        │          │
        │          ├─config
        │          │  │  WebMvcConfig.java mvc配置类,配置拦截器和资源策略
        │          │  │
        │          │  ├─filter # 过滤器
        │          │  │      MainFilter.java
        │          │  │
        │          │  ├─Interceptor # 拦截器
        │          │  │      Intercept.java
        │          │  │      OtherIntercept.java
        │          │  │
        │          │  └─listener # 监听器
        │          │          Listener.java
        │          │
        │          └─controller # 测试Controller
        │                  IndexController.java
        │
        └─resources 
                application.yml # springboot配置

Application.java 启动类代码

package com.base;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

/**
 * 开发公司:个人
 * 版权:个人
 * <p>
 * Application
 * @SpringBootApplication(scanBasePackages = {"com.base"})  scanBasePackages 扫描基础类包
 * @ServletComponentScan(basePackages = {"com.base"}) 扫描服务程序组件 (@WebServlet、@WebFilter、@WebListener等注解注解)
 * 启用@ServletComponentScan 注解后 Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
  * @author 刘志强
 * @created Create Time: 2019/5/23
 */
@SpringBootApplication(scanBasePackages = {"com.base"})
@ServletComponentScan(basePackages = {"com.base"})
public class Application  implements CommandLineRunner {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... strings) throws Exception {
        logger.info("程序启动");
    }
}

用@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。

拦截器

拦截器应用场景

1. 用拦截器控制单点登录
前后端不分离,使用session:
登录
登录时将用户信息存储至session中。
        session.setAttribute("usserId",user.getId());

然后在将userId和sessionId 进行绑定存储至redis(也可以使用别的全局唯一数据源来存储,如静态Map,或别的缓存中间件)
        redisTemplate.opsForValue().set(user.getId(),session.getId());
拦截器判断是否在别处登录
拦截器从session中取出userId
     Long userId = (Long)session.getAttribute("usserId");
    =》 能取到表示已登录。取不到表示未登录或session过期已下线
然后在根据userId从redis中取出sessionId 根据redis中的sessionId
和当前登录sessionId进行比较
     String sessionId = (String) redisTemplate.opsForValue().get(userId);
     if (sessionId === session.getId()) 
    =》 如果一致表示没有在别处登录,如果不一致表示用户已在别处登录(因为如果有另一人在别处登录相同userId的redis会覆盖掉)
前后端分离:
登录
登录时将用户信息存储至redis中。
         redisTemplate.opsForValue().set(token,user.getId());
然后在将userId和token 进行绑定存储至redis(也可以使用别的全局唯一数据源来存储,如静态Map,或别的缓存中间件)
        redisTemplate.opsForValue().set(user.getId(),token);    
拦截器判断是否在别处登录
拦截器从redis中根据token取出userId
     Long userId = (Long)redisTemplate.opsForValue().get(token);
    =》 能取到表示已登录。取不到表示未登录或token过期已下线
然后在根据userId从redis中取出token 根据redis中的token
和当前登录token进行比较
     String redisToken = (String) redisTemplate.opsForValue().get(userId);
     if (redisToken === token) 
    =》 如果一致表示没有在别处登录,如果不一致表示用户已在别处登录(因为如果有另一人在别处登录相同userId的redis会覆盖掉)

Intercept.java

package com.base.config.Interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 拦截器
 */
@Component
public class Intercept implements HandlerInterceptor {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        logger.info("Controller方法调用前,被调用");
        return true;
    }


    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        logger.info("请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        logger.info("在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
    }

}

@Component 创建实例

WebMvcConfig.java 将拦截器实例注册

package com.base.config;

import com.base.config.Interceptor.Intercept;
import com.base.config.Interceptor.OtherIntercept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * 开发公司:个人
 * 版权:刘志强
 * <p>
 * WebMvcConfig
 *
 * @author 刘志强
 * @created Create Time: 2019/2/16
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Autowired
    public Intercept intercept;
    @Autowired
    public OtherIntercept otherIntercept;
    //添加资源处理程序,resources资源目录下的static目录下的资源可以被直接访问
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /**
         * 多个拦截器组成一个拦截器链
         * addPathPatterns 用于添加拦截规则
         * excludePathPatterns 用于排除拦截
         */
        registry.addInterceptor(intercept)
                .addPathPatterns("/**")
                .excludePathPatterns("/index");

        registry.addInterceptor(otherIntercept)
                .addPathPatterns("/**");

        super.addInterceptors(registry);
    }
}

过滤器

MainFilter.java
package com.base.config.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.FilterConfig;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * 开发公司:个人
 * 版权:个人
 * <p>
 * MainFilter
 * @WebFilter(filterName = "mainFilter", urlPatterns = {"/*"})
 * filterName 过滤器名称 urlPatterns 需要过滤的url
 * @author 刘志强
 * @created Create Time: 2019/5/25
 */

@WebFilter(filterName = "mainFilter", urlPatterns = {"/*"})
public class MainFilter implements Filter {

    protected Logger logger = LoggerFactory.getLogger(getClass());


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("过滤器创建");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        logger.info("执行过滤请求");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        logger.info("过滤器销毁");
    }
}

init() 服务器启动时执行,初始化过滤器
doFilter() 对urlPatterns声明请求进行过滤时执行

监听器

Listener.java
package com.base.config.listener;

        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;

        import javax.servlet.ServletContextEvent;
        import javax.servlet.ServletContextListener;
        import javax.servlet.ServletRequestEvent;
        import javax.servlet.ServletRequestListener;
        import javax.servlet.annotation.WebListener;
        import javax.servlet.http.HttpSessionEvent;
        import javax.servlet.http.HttpSessionListener;

/**
 * 开发公司:个人
 * 版权:个人
 * <p>
 * Listener
 *
 * @author 刘志强
 * @created Create Time: 2019/5/25
 */

@WebListener()
public class Listener implements ServletRequestListener, HttpSessionListener,ServletContextListener  {

    protected Logger logger = LoggerFactory.getLogger(getClass());
    // ServletRequestListener start
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        logger.info("监听器到" + servletRequestEvent.getServletRequest().getServerName() + "被销毁");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        logger.info("监听器到" + servletRequestEvent.getServletRequest().getServerName() + "被创建");
    }
    // ServletRequestListener end

    // HttpSessionListener start
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        logger.info("监听器到" + httpSessionEvent.getSession().getId() + "被创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        logger.info("监听器到" + httpSessionEvent.getSession().getId() + "被销毁");
    }
    // HttpSessionListener end

    // ServletContextListener start
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        logger.info("监听器到" + servletContextEvent.getServletContext().getServerInfo() + "被创建");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        logger.info("监听器到" + servletContextEvent.getServletContext().getContextPath() + "被销毁");
    }
    // ServletContextListener end


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值