拦截器(Interceptor)
springboot的核心思想是基于代理模式的,所有的Controller层方法都会被代理,基于代理模式,如果定义了拦截器,springboot就会在调用我们实际的controller代码之前调用拦截器的方法。
springboot定义了一个HandlerInterceptor接口,我们只需要实现这个接口,就可以定义我们自己的拦截器
public class LoginInterceptor implements HandlerInterceptor {
//在执行controller层代码之前执行,如果返回false就直接返回
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if (loginUser == null) {
request.setAttribute("msg","请先登录");
request.getRequestDispatcher("/").forward(request, response);
return false;
}
return true;
}
//controller层代码执行完之后,渲染视图之前
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
//视图渲染之后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
拦截器生效
addPathPatterns定义拦截哪些请求,excludePathPatterns定义排除哪些请求,order定义拦截器执行的顺序,需要注意的是,如果有多个拦截器拦截同一个请求,会按照顺序执行所有的preHandle方法,执行完所有的preHandle方法之后再逆序执行postHandle方法,执行完postHandle再逆序执行afterCompletion
@Configuration
public class WebConfigure implements WebMvcConfigurer {
//addPathPatterns定义拦截哪些请求,excludePathPatterns定义排除哪些请求,order定义拦截器执行的顺序
//需要注意的是,如果有多个拦截器拦截同一个请求,会按照顺序执行所有的preHandle方法,执行完所有的preHandle方法之后再逆序执行
//postHandle方法
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/index","/login")
.excludePathPatterns("/css/**","/fonts/**","/images/**","/js/**").order(1);
registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/index","/login")
.excludePathPatterns("/css/**","/fonts/**","/images/**","/js/**").order(2);
}
}
过滤器(Filter)
- Filter与Interceptor的不同
Interceptor是基于springboot的ioc思想的代理模式,而Filter是基于Servlet容器,二者的实现原理是不一样的。在执行顺序上,springboot在处理Web请求时,是通过注册了一个名为DispatcherServlet的Servlet拦截所有的请求进行处理,所以相当于Controller实际上就是一个Servlet,而在Servlet容器内部,Filter是在Servlet之前执行的,所以Filter是先与Interceptor执行的。
- 新增Filter的方式有很多种,在Springboot中推荐使用下面这种方式
@WebFilter(filterName = "testFilter",urlPatterns = "/*")
@Component
public class TestFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("TestFilter");
filterChain.doFilter(servletRequest,servletResponse);
}
}