SpringMVC(五)【拦截器】

简介: SpringMVC(五)【拦截器】

前言

       今天来把 SpringMVC 最后一部分学完,虽然课时很短,但是学起来还是很慢的,不过确收获很大。不得不感慨学大数据确实有必要把 SSM、SpringBoot 等各种 JavaEE 技术好好学一学,收获很大,尽管我们到现在 Java 代码写了应该20 W 行差不多,但是关于框架的代码我写的还是比较少的,主要是通过算法和 JavaFX 来练习 Java 基础语法。

1、拦截器

1.1、概念

  • 拦截器是一种动态拦截方法调用的机制,在 SpringMVC 中动态拦截控制器方法的执行
  • 作用
  • 在指定方法调用前后执行预先设定的代码
  • 阻止原始方法的执行(权限判断)

拦截器和过滤器的区别

  • 归属不同:Filter 属于 Servlet 技术,Interceptor 属于 SpringMVC 技术
  • 拦截内容不同:Filter 对所有访问进行增强,Interceptor 仅针对 SpringMVC 的访问进行增强

1.2、入门案例

1.2.1、拦截器功能类

       在 controller 包下新建一个包 interceptor ,毕竟拦截器是 SpringMVC 的内容,创建自定义拦截器类(记得添加注解 @Component 让 SpringMVC 来对它进行管理)只需要实现 HandlerInterceptor 接口:

@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 方法的返回值,如果返回值为 false 代表直接截断请求,所以后面的控制器方法不会被执行,后面的 postHandle 和 afterCompletion 方法也不会执行。

       如果返回 true 则代表不拦截,所以它会执行控制器方法以及 postHandle 和 afterCompletion 方法

        在之前的 SpringMvcSupport 类中添加拦截器,需要配置两个参数:拦截器对象(因为拦截器已经被 SpringMVC 所管理了,所以我们直接通过自动装配获得),拦截哪个请求。

访问 localhost:81/books:

上面我们配置的拦截器只能拦截 /books 这一个请求,如果我们想要拦截 /books/2 后者 /books/100 呢,只需要添加一个参数 "/books/*" 即可:

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
    }

1.2.2、简化开发

       现在我们的 SpringMvcConfig 是空的,只是带有一堆注解,我们可以把 SpringMvcSupport 和 SpringMvcConfig 进行合并,其实就是让 SpringMvcConfig 实现 WebMvcConfigurer 接口(和 SpringMvcSupport 很像,后者实现的是 WebMvcConfigurationSupport 接口):

@Configuration
@ComponentScan("com.lyh.controller")
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
 
    @Autowired
    private ProjectInterceptor projectInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
    }
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
 
}

       因为我们已经把 SpringMvcSupport 和 SpringMvcConfig 合并了,所以现在我们就不需要让 SpringMvcConfig 扫描 "com.lyh.config" 包了 。

有无拦截器的区别

可以看到,单个拦截器的时候,如果在 preHandle 方法返回 false,将直接终止执行(afterCompletion 方法也不会执行,但是这种情况在多个拦截器的情况下有所不同)。

1.3、拦截器参数

       我们说拦截器可以帮我们做一些判断,来决定是否允许这个请求进一步进入 controller 方法,那它必然有一些上下文参数

1.3.1、preHandle 方法

  1. HttpServletRequest request
  2. HttpServletResponse response,
  3. Object handler

       对于 request 和 response 这两个对象,我们很容易想到可以拿它们来干什么,比如 request.getHeader("Content-type") 来获得请求头中的 Content-type 属性值。

       而这里的 handler 其实是 HandlerMethod 类,它对反射技术中的 Method 对象进行了封装。我们可以通过它来获得原始执行的方法,具体可以干什么以后用到再学。

1.3.2、postHandle 方法

       postHandle 方法没有 handler 对象,但是它有一个 ModelAndView 对象,如果我们页面跳转的话,可以通过它来设置一些属性,但是我们到目前为止都是返回 json 并不返回页面,所以这里不做学习。

1.3.3、afterCompletion 方法

       afterCompletion 方法同样除了 request 和 response 对象之外,它有一个 Exception 类型的对象,也就是说如果我们的表现层抛出异常的话,我们可以在这里拿到它,但是我们上一篇已经用了 SpringMVC 统一的异常处理器,所以这里也没啥用。

       总之,这三个方法实用性最强的就是 preHandle 方法,它可以决定是否放行请求的下一步执行。

1.4、拦截器链配置

  • 当配置多个拦截器时,形成拦截器链
  • 拦截器的拦截顺序取决于我们 addIterceptors 方法中注册拦截器的顺序

1.4.2、创建拦截器类

我们在 interceptor 包下再创建一个拦截器类:

@Component
public class ProjectInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle2");
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle2");;
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion2");
    }
}

配置拦截器:

访问 localhost:85/books

可以看到,拦截器的拦截顺序取决于我们 addIterceptors 方法中注册拦截器的顺序: pre1 -> pre2 -> controller  -> post2 -> post1 -> after2  -> after1。

注意:多个的拦截器情况下,比如下图:

  • 如果 pre3 返回 flase(pre1 和 pre2都返回 true),那么程序并不是直接终止,而是依然会执行 after2 和 after1;
  • 如果 pre2 返回 flase(pre1返回 true),那么程序并不是直接终止,而是依然会执行 after1;
  • 如果 pre1 返回 flase,那么程序直接终止。

总结

       至此,SpringMVC 的学习结束,SSM 现在已经是一个程序员必知必会的东西了,可以说是一个应届生校招的基本技能,而不是亮点。接下来再学学 SpringBoot ,这是我们大数据开发中正儿八经会用到的东西,完了做个项目巩固巩固。

相关文章
|
前端开发 Java Spring
56SpringMVC - 拦截器
56SpringMVC - 拦截器
37 0
|
5月前
|
XML Java 数据格式
|
6月前
|
数据采集 监控 前端开发
SpringMVC 拦截器
SpringMVC 拦截器
55 0
|
6月前
|
数据安全/隐私保护
SpringMVC拦截器
SpringMVC拦截器
58 0
|
6月前
springMVC之拦截器
springMVC之拦截器
|
Java
SpringMVC-拦截器
SpringMVC-拦截器
57 0
SpringMVC-拦截器
|
前端开发 JavaScript Java
SpringMVC 中的拦截器
SpringMVC 中的拦截器
|
XML 数据格式 容器
springmvc之拦截器
springmvc之拦截器
113 2