SpringMVC拦截器

Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器(自己编写的Controller)进行预处理和后处理。用户可以自己定义一些拦截器来实现特定的功能

拦截器概述

谈到拦截器,还要向大家提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。说到这里,可能大家脑海中有了一个疑问,这不是我们之前学的过滤器吗?是的它和过滤器是有几分相似,但
是也有区别,接下来我们就来说说他们的区别:

类别 使用范围 拦截范围
拦截器 SpringMVC项目 只会拦截访问的控制器方法的请求
过滤器 任何web项目 任何资源(servlet,控制器,jsp,html等)

​ 我们要想自定义拦截器, 要求必须实现: HandlerInterceptor 接口。

自定义拦截器入门

  • 编写一个普通类实现 HandlerInterceptor 接口
package com.jwang.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 包名:com.jwang.interceptor
* @author Leevi
* 日期2020-11-15 10:47
* 拦截器:
* 作用: 在执行controller的方法之前做预处理,以及执行controller的方法之后做后处理
* 步骤:
* 1. 写一个类实现HandlerInterceptor接口
* 2. 选择实现其中的方法:
* 1. preHandle() 在处理器方法之前执行
* 2. postHandle() 在处理器方法之后、视图渲染之前执行
* 3. afterCompletion() 在视图渲染之后执行,官方建议可以在该方法中做一些资源清理操作
* 3. 在springmvc配置文件中进行拦截器的配置(配置拦截器的拦截路径)
*/
public class PermissionInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("PermissionInterceptor的preHandle方法执行了...");
//返回值为true就是放行
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("PermissionInterceptor的postHandle方法执行了...");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("PermissionInterceptor的afterCompletion方法执行了...");
}
}
  • 在springmvc.xml配置拦截器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.jwang"/>

<!--配置拦截器-->
<mvc:interceptors>
<!--
里面可以配置多个拦截器,每一个interceptor就是一个拦截器
-->
<mvc:interceptor>
<!--
mapping表示这个拦截器的拦截范围
-->
<mvc:mapping path="/**" />
<!--
exclude-mapping
-->
<mvc:exclude-mapping path="/hello/sayHaha.do"/>
<!--
bean标签表示对我们要进行配置的拦截器做IOC
-->
<bean id="permissionInterceptor" class="com.jwang.interceptor.PermissionInterceptor"> </bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>

自定义拦截器进阶

拦截器的放行

img

拦截器的路径

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.jwang"/>

<!--配置拦截器-->
<mvc:interceptors>
<!--
里面可以配置多个拦截器,每一个interceptor就是一个拦截器
-->
<mvc:interceptor>
<!--
mapping表示这个拦截器的拦截范围
/**表示拦截所有控制器方法
-->
<mvc:mapping path="/**" />
<!--
exclude-mapping
-->
<mvc:exclude-mapping path="/hello/sayHaha.do"/>
<!--
bean标签表示对我们要进行配置的拦截器做IOC
-->
<bean id="permissionInterceptor" class="com.jwang.interceptor.PermissionInterceptor"> </bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>

拦截器的其它方法

  • afterCompletion  在目标方法完成视图层渲染后执行。
  • postHandle  在目标方法执行完毕获得了返回值后执行。
  • preHandle 被拦截的目标方法执行之前执行。
package com.jwang.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 包名:com.jwang.interceptor
* @author Leevi
* 日期2020-11-15 10:47
* 拦截器:
* 作用: 在执行controller的方法之前做预处理,以及执行controller的方法之后做后处理
* 步骤:
* 1. 写一个类实现HandlerInterceptor接口
* 2. 选择实现其中的方法:
* 1. preHandle() 在处理器方法之前执行
* 2. postHandle() 在处理器方法之后、视图渲染之前执行
* 3. afterCompletion() 在视图渲染之后执行,官方建议可以在该方法中做一些资源清理操作
* 3. 在springmvc配置文件中进行拦截器的配置(配置拦截器的拦截路径)
*/
public class PermissionInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("PermissionInterceptor的preHandle方法执行了...");
//返回值为true就是放行
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("PermissionInterceptor的postHandle方法执行了...");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("PermissionInterceptor的afterCompletion方法执行了...");
}
}

多个拦截器执行顺序

​ 回想多个过滤器的执行顺序:

  1. 如果采用配置文件方式配置过滤器,那么就按照过滤器的配置先后顺序执行

         2. 如果采用注解方式配置过滤器,那么就按照类名的排序执行
    

​ 我们可以配置多个拦截器, 所以就存在一个优先级问题了.多个拦截器的优先级是按照配置的顺序决定的。

img

  • 配置顺序
<!--配置拦截器-->
<mvc:interceptors>
<!--
里面可以配置多个拦截器,每一个interceptor就是一个拦截器
-->
<mvc:interceptor>
<!--
mapping表示这个拦截器的拦截范围
-->
<mvc:mapping path="/**" />
<!--
exclude-mapping
-->
<mvc:exclude-mapping path="/hello/sayHaha.do"/>
<!--
bean标签表示对我们要进行配置的拦截器做IOC
-->
<bean id="permissionInterceptor" class="com.jwang.interceptor.PermissionInterceptor"> </bean>
</mvc:interceptor>

<mvc:interceptor>
<!--
mapping表示这个拦截器的拦截范围
-->
<mvc:mapping path="/**" />
<!--
bean标签表示对我们要进行配置的拦截器做IOC
-->
<bean id="secondInterceptor" class="com.jwang.interceptor.SecondInterceptor"> </bean>
</mvc:interceptor>
</mvc:interceptors>