过滤器拦截器区别:https://blog.csdn.net/jiangtianjiao/article/details/87537614
过滤器配置
一般web项目通过web.xml配置filter,spring boot没有web.xml文件,可以通过以下两种方式配置。
1.通过FilterRegistrationBean配置
public class LogCostFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
long start = System.currentTimeMillis();
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("Execute cost="+(System.currentTimeMillis()-start));
}
@Override
public void destroy() {
}
}
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean registFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new LogCostFilter());
registration.addUrlPatterns("/*");
registration.setName("LogCostFilter");
registration.setOrder(1);
return registration;
}
}
2.通过@WebFilter注解配置,@WebFilter是Servlet3.0的规范,并非spring boot提供。
@WebFilter(urlPatterns = "/*", filterName = "logFilter2")
public class LogCostFilter2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
long start = System.currentTimeMillis();
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("LogFilter2 Execute cost=" + (System.currentTimeMillis() - start));
}
@Override
public void destroy() {
}
}
@SpringBootApplication
@ServletComponentScan("com.pandy.blog.filters") //@ServletComponetScan指定扫描filter包
public class Application {
public static void main(String[] args) throws Exception
SpringApplication.run(Application.class, args);
}
}
注意:@WebFilter注解并没有指定执行顺序的属性,其执行顺序依赖于Filter的名称,根据Filter类名(注意不是配置的filter的名字)的字母顺序倒序排列,并且@WebFilter指定的过滤器优先级高于FilterRegistrationBean配置的过滤器。
拦截器的配置
public class LogCostInterceptor implements HandlerInterceptor {
long start = System.currentTimeMillis();
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o) throws Exception {
// 请求处理前执行
start = System.currentTimeMillis();
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, ModelAndView modelAndView) throws Exception {
// 请求结束后,视图渲染完成前执行
System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) throws Exception {
// 视图渲染完成后执行
}
}
// @
SpringBootApplication中@ComponentScan注解在启动类运行时会自动扫描启动类所在包及其子包@Configuration
publicclass
InterceptorConfig
extends
WebMvcConfigurerAdapter {
继承WebMVCConfigurerAdapter,重写addInterceptors方法,进行拦截器的配置
//
// 主要配置:指定拦截器、指定拦截URL @Override
publicvoid
addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new
LogCostInterceptor()).addPathPatterns(
"/**");
super.addInterceptors(registry);
}
}
可以看到通过拦截器实现了同样的功能。不过这里还要说明一点的是,其实这个实现是有问题的,因为preHandle和postHandle是两个方法,所以我们这里不得不设置一个共享变量start来存储开始值,但是这样就会存在线程安全问题。当然,我们可以通过其他方法来解决,比如通过ThreadLocal就可以很好的解决这个问题。
转载:http://www.cnblogs.com/paddix