SpringMvc中的拦截器

HandlerInterceptorAdapter

拦截器HandlerInterceptor接口有三个回调方法(注释是翻译的源码英文注释,可能略有拗口)
1.preHandle方法

/**
拦截处理程序(接口)。 在 HandlerMapping 确定适当的处理程序对象之后,但在 HandlerAdapter 调用处理程序之前调用。
DispatcherServlet 处理执行链中的处理程序,该处理程序由任意数量的拦截器组成,最后执行被拦截的接口。
使用此方法,每个拦截器都可以决定中止执行链,通常是发送 HTTP 错误或编写自定义响应。
**/
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;

2.postHandle方法,

/**
在 HandlerAdapter 实际调用处理程序之后,但在 DispatcherServlet 呈现视图之前调用。
可以通过给定的 ModelAndView 向视图公开其他模型对象。
DispatcherServlet 处理执行链中的处理程序,该处理程序由任意数量的拦截器组成。
通过postHandle,每个拦截器都可以对执行进行后处理,以执行链的相反顺序应用。
注意:特殊注意事项适用于异步请求处理。
**/
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;

3.afterCompletion方法,

/**
请求处理完成后的回调,即渲染视图后。 将在处理程序执行的任何结果上调用,从而允许适当的资源清理。

  注意:仅当此拦截器的 {@code preHandle} 时才会调用
方法已成功完成并返回 {@code true}!

与 {@code postHandle} 方法一样,该方法将在链中的每个拦截器上以相反的顺序被调用,因此第一个拦截器将是最后一个被调用的拦截器。
**/
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;

实际例子解释运行链条

spring-servlet.xml

<mvc:interceptors>
<bean class="com.interceptor.RateLimitInterceptor">
<property name="urlProperties">
<props>
<prop key="/api/test">200</prop>
</props>
</property>
</bean>
<bean class="com.interceptor.LoginInterceptor"/>
<bean class="com.interceptor.AuthInterceptor">
<constructor-arg index="0" value="#{app.mainSite}"/>
<constructor-arg index="1" value="#{app.context}"/>
<constructor-arg index="2" value="#{app.mode}"/>
<constructor-arg index="3" ref="jedisTemplate"/>
<constructor-arg index="4" value="#{app.domain}"/>
<constructor-arg index="5" value="#{app.htphead}"/>
</bean>
</mvc:interceptors>
 

拦截器的执行顺序:
  在这里插入图片描述

执行结果

每个拦截器的三个方法里面都加了打印----------
1.所有拦截器的preHandle都为true的运行结果如下:
在这里插入图片描述
运行链条:
在这里插入图片描述

2.前两个拦截器prehandle为true,第三个的prehandle为false,结果如下:
在这里插入图片描述
运行链条:
在这里插入图片描述
3.controller方法抛异常在这里插入图片描述
在这里插入图片描述

总结

运行流程总结如下:

1、拦截器执行顺序是按照Spring配置文件中定义的顺序而定的。

2、会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。

3、然后执行主方法(自己的controller接口)若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。

4、在主方法执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的afterCompletion方法。(postHandle和afterCompletion都是倒序执行)
  
下一篇将针对RateLimitInterceptor限流拦截器,进行详细讲解。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值