1.先说拦截器 Interceptor
本项目以springboot为例:
新建
InterceptorConfig
package com.opendev.mystudy.MyInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class InterceptorConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); super.addInterceptors(registry); } }
MyInterceptor
package com.opendev.mystudy.MyInterceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor{ /** * * preHandle是请求执行前执行的,postHandler是请求结束执行的, * 但只有preHandle方法返回true的时候才会执行,afterCompletion是视图渲染完成后才执行, * 同样需要preHandle返回true,该方法通常用于清理资源等工作。 * */ long start = System.currentTimeMillis(); @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("preHandle。。。"); start = System.currentTimeMillis(); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("postHandle。。。"); System.out.println("Interceptor cost="+(System.currentTimeMillis()-start)); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("afterCompletion。。。"); } }
执行的顺序如下
2.再说说 Filter ,先集成到配置类中
FiterConfig
package com.opendev.mystudy.MyFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FilterConfig { @Bean public FilterRegistrationBean registFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new MyFilter()); registration.addUrlPatterns("/test/frist/*"); registration.setName("MyFilter"); registration.setOrder(1); return registration; } }
MyFilter
package com.opendev.mystudy.MyFilter; import javax.servlet.*; import javax.servlet.FilterConfig; import javax.servlet.annotation.WebFilter; import java.io.IOException; /** * 用这个@WebFilter就要在主类上配置@ServletComponentScan */ //@ServletComponentScan("com.opendev.mystudy.MyFilter") @WebFilter(urlPatterns = "/*", filterName = "MyFilter") public class MyFilter implements Filter { /** * * servlet 初始化过程 * @param filterConfig * @throws ServletException */ @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("进入了 init 方法"); } /** * * 这段代码的逻辑比较简单,就是在方法执行前先记录时间戳, * 然后通过过滤器链完成请求的执行,在返回结果之间计算执行的时间。 * 这里需要主要,这个类必须继承Filter类,这个是Servlet的规范, * 这个跟以前的Web项目没区别。但是,有了过滤器类以后, * 以前的web项目可以在web.xml中进行配置,但是spring boot项目并没有web.xml这个文件, * * @param servletRequest * @param servletResponse * @param filterChain * @throws IOException * @throws ServletException */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("进入了 doFilter 方法"); long start = System.currentTimeMillis(); filterChain.doFilter(servletRequest,servletResponse); System.out.println("Execute cost="+(System.currentTimeMillis()-start)); } @Override public void destroy() { System.out.println("进入了 destroy 方法"); } }
二者的方法都是访问controller为
package com.opendev.mystudy.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/test") public class MyController { @RequestMapping(value = "/frist",method = RequestMethod.GET) public void TestController() throws InterruptedException { System.out.println("-----------------"); Thread.sleep(2000); } }
3.以上二者的分别使用,现在把他们二个集成使用看
从上面打印的日志就可以看,过滤器比拦截器先执行。
总结:过滤器比拦截器先执行