拦截器
# 拦截器
主要用于拦截即将抵达controller的请求,可用于权限检测等行为。 ![[Pasted image 20220616150636.png]]
# 流程图
![[Pasted image 20220616154122.png]]
# 拦截器与过滤器
- 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术。
- 拦截内容不同: Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强。
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVCConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
这是我们主配置类的代码,从代码中可见
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
1
2
3
4
2
3
4
我们配置了可访问/
以下所有路径,这就是Servlet的Filter,位于访问的最外层,倘若我们改成/book
那么就只能访问/book
路径下的内容了,相当于大门守卫,而拦截器等同于屋内的管家。
# 案例
我们需要创建一个继承自HandlerInterceptor
接口的类,然后重写三个方法。
// controller/interceptor/ProjectInterceptor
@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");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// config/SpringMVCSupport
@Configuration
public class SpringMVCSupport extends WebMvcConfigurationSupport {
@Autowired
ProjectInterceptor pi;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(pi).addPathPatterns("/users");
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
@Configuration
@ComponentScan({"com.project.controller","com.project.config"})
@EnableWebMvc
public class SpringMVCConfig {
}
1
2
3
4
5
2
3
4
5
这样一来,当用户访问/users
路径后,就会触发拦截器
输出: preHandle [INFO] {dataSource-1} inited postHandle afterCompletion
上面的案例并未完善,他真的只能拦截/users
的请求而已,如果你访问/users/1
他就失效了,但后面的数字是个变量,这怎么搞吖???
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(pi).addPathPatterns("/users","/users/*");
}
1
2
3
4
2
3
4
addPathPatterns
支持多路径参数,因此你可以写多个路径,并且也支持*
作为任意字符
好麻烦啊!!!为实现这个操作上面得多写那么多代码,怎么记得住啊!!!!
# 简化开发
事实上,你可以在SpringMVCConfig
这个类上继承一个WebMvcConfigurer
的接口,该接口和先前SpringMVCSupport
继承的WebMvcConfigurationSupport
类是一模一样的。这样你就能把SpringMVCSupport
写的内容放在SpringMVCConfig
类中,简化了开发
@Configuration
@ComponentScan({"com.project.controller"})
@EnableWebMvc
public class SpringMVCConfig implements WebMvcConfigurer {
@Autowired
ProjectInterceptor pi;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(pi).addPathPatterns("/users","/users/*");
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11