SpringBoot中的Filter与Interceptor
2018-03-22 15:43
399 查看
SpringBoot中的Filter与Interceptor
韩子昂(2018.03.22)一、项目环境
开发工具:IDEAJDK:1.8
项目框架:SpringBoot 1.0.4 + Maven
二、过滤器配置及使用
用log4j记录Filter的处理过程import org.slf4j.Logger; import org.slf4j.LoggerFactory; //urlPatterns中填入你想过滤的请求地址 @WebFilter(filterName = "userFilter" , urlPatterns = "/*") public class UserFilter implements Filter { private static Logger logger = LoggerFactory.getLogger(UserFilter.class); @Override public void init(FilterConfig filterConfig) throws ServletException { logger.info("----------------过滤器正在启动-----------------"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; String requestURI = request.getRequestURI(); logger.info("----------------过滤器正在处理-----------------"); logger.info("该请求为:"+requestURI); filterChain.doFilter(request, response); } @Override public void destroy() { } }
别忘了在Springboot的启动类中添加注解扫描@ServletComponentScan
启动的时候可以看到SpringBoot的后台日志输出
2018-03-22 11:15:31.916 INFO 1032 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'userFilter' to urls: [/*] 2018-03-22 11:15:31.937 INFO 1032 --- [ost-startStop-1] com.example.app.web.filter.UserFilter : ----------------过滤器正在启动-----------------
访问指定路径后端控制台日志如下:
2018-03-22 14:16:22.965 INFO 10208 --- [nio-8080-exec-2] com.example.app.web.filter.UserFilter : ----------------过滤器正在处理----------------- 2018-03-22 14:16:22.966 INFO 10208 --- [nio-8080-exec-2] com.example.app.web.filter.UserFilter : 过滤的该请求为:/user/login.do 2018-03-22 14:16:23.677 INFO 10208 --- [nio-8080-exec-4] com.example.app.web.filter.UserFilter : ----------------过滤器正在处理----------------- 2018-03-22 14:16:23.678 INFO 10208 --- [nio-8080-exec-4] com.example.app.web.filter.UserFilter : 过滤的该请求为:/user/getManager
还可以指定Filter过滤异步ajax请求,可以通过requst.getHeader(),判断请求头是否为”XMLHttpRequest“,若是的话则为异步ajax请求。
private static String ajaxHeader = "XMLHttpRequest"; //在doFilter方法中: if (StringUtils.equals(request.getHeader("X-Requested-With"),ajaxHeader)) { logger.info("接收到ajax异步请求"); }
上面一段代码中有StringUtils,那个是apache提供的字符串工具类,其中的.equals方法可以避免常规equals方法抛出空指针异常的错误,是个非常好用的工具类。
页面发送一个/user/login.do的登录ajax请求到后端,可以看到控制台打印出日志:
2018-03-22 14:29:18.210 INFO 11716 --- [nio-8080-exec-1] com.example.app.web.filter.UserFilter : ----------------过滤器正在处理----------------- 2018-03-22 14:29:18.210 INFO 11716 --- [nio-8080-exec-1] com.example.app.web.filter.UserFilter : 过滤的该请求为:/user/login.do 2018-03-22 14:29:18.212 INFO 11716 --- [nio-8080-exec-1] com.example.app.web.filter.UserFilter : 接收到ajax异步请求
三、拦截器的配置及使用
使用拦截器的时候要明白,拦截器是Spring提供的,需要新建两个类,分别是UserInterceptor拦截器类,与WebConfig配置类。
首先是拦截器类,需要实现HandlerInterceptor的接口。在preHandle方法中可以进行判断,return true放行该请求,false则拦截阻止该请求。
public class UserInterceptor implements HandlerInterceptor { private static Logger logger = LoggerFactory.getLogger(UserInterceptor.class); @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { logger.info("---------------拦截器正在处理----------------"); logger.info("拦截的该请求为:"+httpServletRequest.getRequestURI()); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
接下来是第二个类,WebConfig配置类,注意需要添加@Configuration注解:
@Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { super.addInterceptors(registry); //添加拦截器 registry.addInterceptor(new UserInterceptor()). addPathPatterns("/**").excludePathPatterns("/user/login.do"); } }
可以不断添加addPathPatterns()来指定要拦截的请求地址,excludePathPatterns()是指定忽略拦截的请求。
访问指定请求地址后,可见后端控制台日志输出:
2018-03-22 15:10:31.768 INFO 2432 --- [nio-8080-exec-3] c.e.app.web.interceptor.UserInterceptor : ---------------拦截器正在处理---------------- 2018-03-22 15:10:31.768 INFO 2432 --- [nio-8080-exec-3] c.e.app.web.interceptor.UserInterceptor : 拦截的该请求为:/user/getManager
四、过滤器Filter与拦截器Interceptor的区别
就个人目前来看,最大的区别是Filter过滤器可以作用于Servlet及Controller。而拦截器无法拦截到发送至Servlet中的请求,只能拦截到Controller中的。从后端控制台日志可以看出:
2018-03-22 15:27:23.208 INFO 5824 --- [nio-8080-exec-5] com.example.app.web.filter.UserFilter : ----------------过滤器正在处理----------------- 2018-03-22 15:27:23.208 INFO 5824 --- [nio-8080-exec-5] com.example.app.web.filter.UserFilter : 过滤的该请求为:/user/login.do 2018-03-22 15:27:23.372 INFO 5824 --- [nio-8080-exec-4] com.example.app.web.filter.UserFilter : ----------------过滤器正在处理----------------- 2018-03-22 15:27:23.372 INFO 5824 --- [nio-8080-exec-6] com.example.app.web.filter.UserFilter : ----------------过滤器正在处理----------------- 2018-03-22 15:27:23.372 INFO 5824 --- [nio-8080-exec-4] com.example.app.web.filter.UserFilter : 过滤的该请求为:/userSevlet 2018-03-22 15:27:23.372 INFO 5824 --- [nio-8080-exec-6] com.example.app.web.filter.UserFilter : 过滤的该请求为:/user/getManager 2018-03-22 15:27:23.372 INFO 5824 --- [nio-8080-exec-6] c.e.app.web.interceptor.UserInterceptor : ---------------拦截器正在处理---------------- 2018-03-22 15:27:23.373 INFO 5824 --- [nio-8080-exec-6] c.e.app.web.interceptor.UserInterceptor : 拦截的该请求为:/user/getManager
可见拦截器并没有拦截到发送到UserServlet的请求,且过滤前执行全都在拦截器之前。
说明我们在搭建项目的时候就应该考虑应该使用Servlet还是使用Controller去处理请求。不过建议在Spring的框架下尽量使用拦截器。
以下是我在别处找到的过滤器与拦截器的不同之处,可供参考:
1. 拦截器是基于动态代理的,而过滤器是基于函数回调。
2. 拦截器不依赖于servlet容器,通过动态代理实现,过滤器依赖于servlet容器。
3. 拦截器可以在方法前后,异常前后等调用,而过滤器只能在请求前和请求后各调用一次。
4. 拦截器可以利用依赖注入,因此在Spring框架程序中,优先拦截器。
[注]:动态代理,学过python的朋友知道装饰器的话,动态代理就与python中的装饰器相类似。都是为了提高代码的可维护性。如果没学过,只能跟你解释说类似于游戏中的装备附魔,可以给它附加上额外的功能。比如给方法中加入日志,权限的功能,而不用去修改源代码。
过滤器与拦截器的执行顺序
如图:相关文章推荐
- Spring Boot 编写Servlet、Filter、Listener、Interceptor的方法
- Spring Boot参考教程(六)Spring Boot配置Servlet,Filter,Listener,Interceptor
- spring boot (二) servlet listener filter interceptor
- springboot(五)filter/interceptor/listener
- SpringBoot 自定义filter 和 interceptor,自定义静态文件存放位置
- Spring Boot之Filter和Interceptor的对比分析
- spring boot RESTFul API拦截 以及Filter和interceptor 、Aspect区别
- Spring Boot中Servlet&Filter&Listener&Interceptor的使用
- Spring Boot 之Servlet、Listener、Filter
- SpringBoot添加filter
- spring-boot如何定义一个servlet,filter,listener
- Spring-boot中配置拦截器(Filter)
- 非spring组件servlet、filter、interceptor中注入spring bean
- Spring Boot使用HandlerInterceptorAdapter和WebMvcConfigurerAdapter实现原始的登录验证
- spring-boot-started-logging logback常用配置之<filter>标签详解
- SpringBoot初始教程之Servlet、Filter、Listener配置
- springboot系列教程(九)——Servlet、Filter、Listener
- Spring-boot添加Filter - OpenSessionInViewFilter
- spring boot(18)-servlet、filter、listener
- spring-in-action-mvc-interceptor-filter