拦截器
是指通过统一拦截浏览器向服务器发送的请求并进行增强的东西。主要应用例如:编码,权限验证。
过滤器
依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。类似公路上的收费站。
共同点
抛开细节,过滤器和拦截器的功能非常相似。
实现一个拦截器,
1.实现HandlerInterceptor接口,实现三个方法。
2.注册拦截器,springboot是编写一个配置类继承WebMvcConfigurerAdapter重写addInterceptors方法注册
3.如果需要配置拦截规则,可以自行配置,参考官网文档把。
1 package com.example.demo;
2
3 import org.springframework.web.servlet.HandlerInterceptor;
4 import org.springframework.web.servlet.ModelAndView;
5
6 import javax.servlet.http.HttpServletRequest;
7 import javax.servlet.http.HttpServletResponse;
8
9 /**
10 * Created by 20160216 on 2018/2/8.
11 */
12 public class SessionInterceptor implements HandlerInterceptor
13 {
14 @Override
15 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
16 System.out.println("uri="+request.getRequestURI());
17 //登录不做拦截
18 if(request.getRequestURI().equals("/userbg/login") || request.getRequestURI().equals("/user/login_view"))
19 {
20 return true;
21 }
22 //验证session是否存在
23 Object obj = request.getSession().getAttribute("_session_user");
24 if(obj == null)
25 {
26 response.sendRedirect("/user/login_view");
27 return false;
28 }
29 return true;
30 }
31
32 @Override
33 public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
34
35 }
36
37 @Override
38 public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
39
40 }
41 }
定义拦截器
1 @Configuration
2 public class MyMvcConfig extends WebMvcConfigurerAdapter {
3 /**
4 * 静态资源配置
5 */
6 /*@Override
7 public void addResourceHandlers(ResourceHandlerRegistry registry) {
8 registry.addResourceHandler("/img/**")
9 .addResourceLocations("classpath:/imgs/");
10
11 super.addResourceHandlers(registry);
12 }*/
13
14 /**
15 * 默认首页配置
16 */
17 @Override
18 public void addViewControllers(ViewControllerRegistry registry) {
19 registry.addViewController("/").setViewName("forward:/index");
20 registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
21 super.addViewControllers(registry);
22 }
23
24 /**
25 * interceptor配置
26 */
27 @Override
28 public void addInterceptors(InterceptorRegistry registry) {
29 registry.addInterceptor(new SessionInterceptor())
30 //添加需要验证登录用户操作权限的请求
31 .addPathPatterns("/**")
32 //排除不需要验证登录用户操作权限的请求
33 .excludePathPatterns("/css/**")
34 .excludePathPatterns("/js/**")
35 .excludePathPatterns("/images/**");
36 }
37 }
注册拦截器
关于刚刚实现的方法
1.preHandle在请求之前调用,返回值可以继续或终止请求,参数有res,rep,obj,表示的是当前请求的目标对象,就是controller实例。
2.postHandle是请求后调用,可以改变视图或者修改发往视图的方法,参数req,res,obj,mv。
3.afterCompletion请求结束调用。
执行多个拦截器
先执行拦截器1的pre >>> 拦截器2的pre >>> 拦截器2的post >>> 拦截器1的post >>> 拦截器2的afterCompletion >>> 拦截器1的afterCompletion
拦截器其他实现方式
1可以实现WebRequestInterceptor方法,但是功能没有上面的强大,一般不用.
拦截器和过滤器的区别
Filte依赖Servlet容器,基于回调函数,过滤范围大。
Interceptor依赖框架容器,基于反射机制,至过滤请求。
这张图是加了过滤器和拦截器的springmvc执行顺序