Spring拦截器&过滤器
一、拦截器 Interceptor
实现HandlerInterceptor接口,并重写以下方法
preHandle(..):在实际处理程序运行之前
postHandle(..): 处理程序运行后
afterCompletion(..): 完成请求后
preHandle方法返回一个布尔值,可以使用此方法中断或继续执行链的处理。当此方法返回true时,处理程序执行链继续;当返回false时,DispatcherServlet 假定拦截器本身已经处理了请求(并且,例如,呈现了适当的视图)并且不会继续执行其他拦截器和执行链中的实际处理程序
1、定义拦截器
public class MyInterceptor implements HandlerInterceptor { /** * controller执行前调用此方法 * 返回true表示继续执行,返回false中止执行 * 这里可以加入登录校验、权限拦截等 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("interceptor preHandle"); return true; } /** * controller执行后但未返回视图前调用此方法 * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示(比如:菜单导航) */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("interceptor postHandle"); // TODO } /** * controller执行后但未返回视图前调用此方法 * 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示(比如:菜单导航) */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("interceptor afterCompletion"); // TODO } }
2、注册拦截器
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LocaleChangeInterceptor()); registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**"); registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*"); } }
xml配置方式:
<mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/admin/**"/> <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/secure/*"/> <bean class="org.example.SecurityInterceptor"/> </mvc:interceptor> </mvc:interceptors>
注意:在springboot项目中不必使用@EnableWebMvc 注解,因为@EnableWebMvc 注解会导致WebMvcAutoConfiguration失效,也就是Springboot的自动配置机制失效
原因:
@EnableWebMvc 注解会通过 import 引入 @Configuration 注解的类 DelegatingWebMvcConfiguration,然后 DelegatingWebMvcConfiguration 类又继承了 WebMvcConfigurationSupport 类。
最后,在 WebMvcAutoConfiguration 类中有一个 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 注解,其意义是,当没有 WebMvcConfigurationSupport 类时,WebMvcAutoConfiguration(即 SpringMvc 的自动配置类)才会生效。
因此,继承 WebMvcConfigurationSupport 会导致 SpringMvc 的自动配置类失效
二、过滤器 Filter
过滤器能起到拦截请求并做出相应动作。比如可以进行登录过滤等
实现方式:实现Filter接口、实现AbstractFilter抽象类
1、定义过滤器(实现Filter接口)
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; import java.io.IOException; @WebFilter(filterName = "myFilter", urlPatterns = "/*", initParams = { @WebInitParam(name = "name", value = "yang")}) public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("filter init"); String name = filterConfig.getInitParameter("name"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("filter doFilter"); chain.doFilter(request, response); } @Override public void destroy() { System.out.println("filter destroy"); } }
2、注册Filter
有以下两种方式:
①:在Filter上添加@Component注解
②:Spring启动类上添加 @ServletComponentScan注解
Springboot中注册拦截器:
@Configuration
public class FilterConfig {
@Bean
FilterRegistrationBean<Filter01> filter01FilterRegistrationBean() {
FilterRegistrationBean<Filter01> bean = new FilterRegistrationBean<>();
bean.setFilter(new Filter01());
bean.setOrder(99);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
}
三、Interceptor、Filter、Aop执行顺序
filter init
filter doFilter
interceptor preHandle
aop start
hello controller
aop end
interceptor postHandle
interceptor afterCompletion
END.