[SpringMVC笔记] SpringMVC-16-拦截器入门

SpringMVC-16-拦截器入门

1、定义拦截器的 bean

拦截器(Interceptor)的代码和 aop 很相似,实现 HandlerInterceptor 接口,重写其中的 preHandle,postHandle,afterCompletion 三个函数

  • preHandle 函数:执行在 Controller 方法之前,返回一个 boolean 值,返回 true 则放行,返回 false 则阻止且不再进行后续操作
  • postHandle 函数:执行在 Controller 方法之后,DispatcherServlet 进行视图的渲染之前,参数中有 modelAndView,可以对其进行操作
  • afterCompletion 函数:执行在 DispatcherServlet 进行视图的渲染之后

执行流程:preHandle函数 -> Controller方法 -> postHandle函数 -> DispatcherServlet渲染试图 -> afterCompletion函数

如果 preHandle函数返回 false,那么后续的操作都不会发生

@Component
public class ProjectInterceptor implements HandlerInterceptor {
    // 模拟判断请求中是否包含代表已经登录的 cookie,是则放行,否则阻止
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...");
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("hasLogged") && cookie.getValue().equals("true")) {
                cookie.setMaxAge(60 * 60 * 24 * 7); // 若已登录,刷新 cookie 持续时间
                response.addCookie(cookie);
                return true;
            }
        }
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("<center>请先登录。<center/>");
        return false;
    }

    @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...");
    }
}

[补充]

  • postHandle 和 afterCompletion 方法中对 response 操作(比如添加 cookie)都不会带给客户端

2、定义配置类

拦截器的配置类和设置静态资源放行的配置类同样继承自 WebMvcConfigurationSupport,而且设置方法也很相似,要重写 addInterceptors 方法

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    // 自动装配拦截器
    @Autowired 
    private ProjectInterceptor interceptor;

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器,前为拦截器对象实例,后为需要拦截的路径
        registry.addInterceptor(interceptor).addPathPatterns("/books", "/books/*");
    }
}

3、使 SpringMVC 配置类能够扫描到拦截器和配置类

// 拦截器在 controller 包下,配置类在 config 包下
@Configuration
@ComponentScan({"com.mzz.controller", "com.mzz.config"})
@EnableWebMvc
public class SpringMvcConfig {
}

4、简化开发

SpringMVC 的核心配置类可以实现 WebMvcConfigurer 接口,再重写其中的 addInterceptors 方法,就不需要再单独定义拦截器的配置类,相当于合并了前面的第 2、3 步

同样的,处理放行静态资源的 addResourceHandlers 方法也在此接口中,可以一并重写,如下例

@Configuration
@ComponentScan({"com.mzz.controller"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ProjectInterceptor interceptor;
    // 添加拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor).addPathPatterns("/books", "/books/*");
    }
    // 处理静态资源
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/page/**").addResourceLocations("/html/");
    }
}

然而这种形式侵入性较强,了解即可


部分资料参考自:https://www.cnblogs.com/yanze/p/11057102.html

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...