拦截器
- 拦截器是一种动态拦截方法调用的机制
- 作用
- 在指定的方法调用前后预先执行设定后的代码
- 阻止原始方法的执行
拦截器与过滤器的区别
- 归属不同:Filter属于servlet技术,Interceptor属于SpringMVC技术
- 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
实现拦截器(配置类)
- 1.声明拦截器的bean,并实现HandlerInterceptor接口(注意:扫描加载bean)
@Component
public class ProjectInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
preHandle:适配器适配之后,处理器方法执行之前调用,如果返回值为true,则继续调用处理器方法,执行后续操作,如果范围false,则表示被拦截,处理器方法以及后续的操作将不再执行
postHandle:在处理器方法执行之后调用
afterCompletion:视图渲染之后才会被调用
- 2.定义配置类,继承,实现方法(注意:扫描加载配置)
在SpringMVCConfig中扫描
@Configuration
@EnableWebMvc
@ComponentScan({"com.cmq.controller","com.cmq.config"})
public class SpringMVCConfig {
}
- 3.添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个
/*设置对静态资源的访问放行*/
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Autowired
private ProjectInterceptor projectInterceptor;
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages");
}
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(projectInterceptor).addPathPatterns("/users","/users/*");
}
}
- 4.使用标准接口WebMvcConfigurer简化开发(注意:侵入式较强)
@Configuration
@EnableWebMvc
@ComponentScan("com.cmq.controller")
public class SpringMVCConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor projectInterceptor;
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(projectInterceptor).addPathPatterns("/users","/books/*");
}
}
拦截器(Interceptor)的配置
在自定拦截器完成后,就是在Spring MVC 中配置拦截器(Interceptor)了,可以通过Java配置类的方式进行配置,也可以通过xml文件的方式进行配置。
一、Java配置类的方式
- @EnableWebMvc : 表示启用Spring MVC的功能
- @Configuration: 表示该类是Spring 中的配置类
- 拦截的配置需要重写WebMvcConfigurer 的addInterceptors(InterceptorRegistry registry) 方法,通过registry进行添加(默认拦截所有)
- 可以通过addPathPatterns来表示拦截哪些请求
- 可以通过excludePathPatterns不拦截哪些请求
对于URI匹配模式:
- ?:匹配一个字符
- *:匹配路径段中的零个或者多个字符
- **:匹配零个或者多个路径段
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
registry.addInterceptor(new LocaleChangeInterceptor());
registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
}
}
二、xml文件的方式
<mvc:interceptors>
<bean class="com.example.web.interceptor.MyInterceptor"/>
<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>
流程
只考虑preHandle为true的情况