springboot实现拦截器、过滤器、监听器
此篇记录Springboot实现拦截器、过滤器、监听器。
拦截器
一、创建拦截器
例如:拦截没有登录的用户跳转登录界面
首先创建一个登录拦截器LoginInterceptor继承HandlerInterceptor然后实现父类的方法:
preHandle 在请求处理之前进行调用(Controller方法调用之前)
返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器
postHandle 在请求处理之后进行调用(Controller方法调用之后)
afterCompletion 整个请求处理完毕回调方法,即在视图渲染完毕时回调,
如果要拦截没有登录用户则需要在请求处理之前进行判断,所以实现preHandle方法,例如:
拦截器代码如下:
package com.wh.interceptor; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Description //TODO * @Author wanghao * @Date 2019-09-10 22:25 **/ @Component public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("进入拦截器,访问的url路径为:"+request.getServletPath()); String user = (String) request.getSession().getAttribute("userInfo"); System.out.println("出去拦截器,获取的user为:"+user); return !StringUtils.isEmpty(user); } }
二、配置config管理类
package com.wh.config; import com.wh.interceptor.LoginInterceptor; 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.WebMvcConfigurer; /** * @Description //TODO * @Author wanghao * @Date 2019-09-10 22:40 **/ @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 添加拦截器loginInterceptor 拦截路径为/** 所有,排除路径为/login registry.addInterceptor(loginInterceptor).addPathPatterns("/**") .excludePathPatterns("/login"); } }
三、测试
首先进入test路径打印如下:
页面返回为空。是因为没有userInfo存在,所以被拦截了。
然后访问login,set用户信息,再次进入 test
如上全部测试打印信息,第一次没有user,所以被拦截了。进入login方法后,set了user,就放行了。
如果我们拦截后进行信息打印或者跳转登录页面,都可以进行修改返回的操作。如下图所示;
例如访问test打印的是:
四、多个拦截器执行顺序
添加的顺序进行改变后,打印信息如下:
所以执行顺序和添加顺序有关,例如先添加的1、然后添加的2,3则执行顺序为:
过滤器
过滤器与拦截器配置类似,
一、新建过滤器
package com.wh.filter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class MyFilter implements Filter { Logger logger = LoggerFactory.getLogger(MyFilter.class); @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest request1 = (HttpServletRequest) request; logger.info("进入MyFilter 请求URl: "+ request1.getContextPath());
// 注:如果不下下面这一句则不会往后面执行,相当于被拦截了 chain.doFilter(request, response); } @Override public void destroy() {} }
二、配置过滤器,依然在上面拦截器的配置类里面配置如下代码:
package com.wh.config; import com.wh.filter.MyFilter; import com.wh.filter.MyFilter2; import com.wh.interceptor.LoginInterceptor; import com.wh.interceptor.SensitiveInfoInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @Description //TODO * @Author wanghao * @Date 2019-09-10 22:40 **/ @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired LoginInterceptor loginInterceptor; @Autowired SensitiveInfoInterceptor sensitiveInfoInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 添加拦截器loginInterceptor 拦截路径为/** 所有,排除路径为/login // registry.addInterceptor(sensitiveInfoInterceptor).addPathPatterns("/**") // .excludePathPatterns("/login"); // registry.addInterceptor(loginInterceptor).addPathPatterns("/**") // .excludePathPatterns("/login"); } @Bean public FilterRegistrationBean<MyFilter> filter1() { FilterRegistrationBean<MyFilter> filterRegBean = new FilterRegistrationBean<>(); filterRegBean.setFilter(new MyFilter()); // /* 所有请求 filterRegBean.addUrlPatterns("/*"); filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1); return filterRegBean; } }
三、结果
如下图所示:正常进入过滤器,
四、过滤链
新建MyFilter2此处略
然后在config中添加MyFilter的配置如下:
package com.wh.config; import com.wh.filter.MyFilter; import com.wh.filter.MyFilter2; import com.wh.interceptor.LoginInterceptor; import com.wh.interceptor.SensitiveInfoInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @Description //TODO * @Author wanghao * @Date 2019-09-10 22:40 **/ @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired LoginInterceptor loginInterceptor; @Autowired SensitiveInfoInterceptor sensitiveInfoInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 添加拦截器loginInterceptor 拦截路径为/** 所有,排除路径为/login // registry.addInterceptor(sensitiveInfoInterceptor).addPathPatterns("/**") // .excludePathPatterns("/login"); // registry.addInterceptor(loginInterceptor).addPathPatterns("/**") // .excludePathPatterns("/login"); } @Bean public FilterRegistrationBean<MyFilter> filter1() { FilterRegistrationBean<MyFilter> filterRegBean = new FilterRegistrationBean<>(); filterRegBean.setFilter(new MyFilter()); // /* 所有请求 filterRegBean.addUrlPatterns("/*"); // order 越小优先级越高 filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1); return filterRegBean; } @Bean public FilterRegistrationBean<MyFilter2> filter2() { FilterRegistrationBean<MyFilter2> filterRegBean = new FilterRegistrationBean<>(); filterRegBean.setFilter(new MyFilter2()); // /* 所有请求 filterRegBean.addUrlPatterns("/*"); // order 越小优先级越高 filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2); return filterRegBean; } }
结果如下图所示;优先执行了Order小的一个,Filter2,所以配置多个过滤器的时候,Order越小则优先级越高。
常用的字符乱码过滤器:
@Bean public FilterRegistrationBean characterEncodingFilterRegister(){ FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(); CharacterEncodingFilter characterEncodingFilter=new CharacterEncodingFilter(); characterEncodingFilter.setForceEncoding(true); characterEncodingFilter.setEncoding("UTF-8"); filterRegistrationBean.setFilter(characterEncodingFilter); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE+1); return filterRegistrationBean; }
不过一般都在配置文件这样配置:
# 设置请求响应的字符编码 spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true spring.http.encoding.force=true
监听器
一、创建监听器
package com.wh.listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** * 创建监听Session */ public class MyHttpSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("创建Session 请求Url" + se.getSession().getServletContext().getContextPath()); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("销毁Session"); } }
二、配置config
@Bean public ServletListenerRegistrationBean listener1(){ ServletListenerRegistrationBean srb = new ServletListenerRegistrationBean(); srb.setListener(new MyHttpSessionListener()); return srb; }
三、结果
四、监听器补充
1.ServletContextListener -- 监听servletContext对象的创建以及销毁 1.1 contextInitialized(ServletContextEvent arg0) -- 创建时执行 1.2 contextDestroyed(ServletContextEvent arg0) -- 销毁时执行 2.HttpSessionListener -- 监听session对象的创建以及销毁 2.2 sessionCreated(HttpSessionEvent se) -- 创建时执行 2.2 sessionDestroyed(HttpSessionEvent se) -- 销毁时执行 3.ServletRequestListener -- 监听request对象的创建以及销毁 3.1 requestInitialized(ServletRequestEvent sre) -- 创建时执行 3.2 requestDestroyed(ServletRequestEvent sre) -- 销毁时执行 4.ServletContextAttributeListener -- 监听servletContext对象中属性的改变 4.1 attributeAdded(ServletContextAttributeEvent event) -- 添加属性时执行 4.2 attributeReplaced(ServletContextAttributeEvent event) -- 修改属性时执行 4.3 attributeRemoved(ServletContextAttributeEvent event) -- 删除属性时执行 5.HttpSessionAttributeListener --监听session对象中属性的改变 5.1 attributeAdded(HttpSessionBindingEvent event) -- 添加属性时执行 5.2 attributeReplaced(HttpSessionBindingEvent event) -- 修改属性时执行 5.3 attributeRemoved(HttpSessionBindingEvent event) -- 删除属性时执行 6.ServletRequestAttributeListener --监听request对象中属性的改变 6.1 attributeAdded(ServletRequestAttributeEvent srae) -- 添加属性时执行 6.2 attributeReplaced(ServletRequestAttributeEvent srae) -- 修改属性时执行 6.3 attributeRemoved(ServletRequestAttributeEvent srae) -- 删除属性时执行
引用资料:
https://www.cnblogs.com/hhhshct/p/8808115.html
https://blog.csdn.net/m0_38075425/article/details/81164501
扩展资料: