# springboot-base-five **Repository Path**: springbook_foundation/springboot-base-five ## Basic Information - **Project Name**: springboot-base-five - **Description**: springboot 集成 拦截器,过滤器,监听器 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2019-05-25 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## [springboot官方文档](http://spring.io/projects/spring-boot) ## [本项目地址](https://gitee.com/springbook_foundation/springboot-base-five) ### 项目目录 ```bash │ 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 } ```