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;

/**
 * 开发公司:个人
 * 版权:个人
 * 

* 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;

/**
 * 开发公司:个人
 * 版权:刘志强
 * 

* 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;

/**
 * 开发公司:个人
 * 版权:个人
 * 

* 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;

/**
 * 开发公司:个人
 * 版权:个人
 * 

* 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 }

你可能感兴趣的:(后端,拦截器,过滤器,监听器)