首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >不讲废话,全程干货,0基础带你学习SpringMVC拦截处理器

不讲废话,全程干货,0基础带你学习SpringMVC拦截处理器

作者头像
JavaEdge
修改2025-05-07 21:24:08
修改2025-05-07 21:24:08
3610
举报
文章被收录于专栏:JavaEdgeJavaEdge

本文已收录在Github关注我,紧跟本系列专栏文章,咱们下篇再续!

  • 🚀 魔都架构师 | 全网30W技术追随者
  • 🔧 大厂分布式系统/数据中台实战专家
  • 🏆 主导交易系统百万级流量调优 & 车联网平台架构
  • 🧠 AIGC应用开发先行者 | 区块链落地实践者
  • 🌍 以技术驱动创新,我们的征途是改变世界!
  • 👉 实战干货:编程严选网

1 工作原理流程图

2 Spring Web MVC 的处理器拦截器

代码语言:java
复制
public interface HandlerInterceptor {

	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return true;
	}

	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}

}

类似Servlet的过滤器Filter,对处理器进行预处理、后处理。HandlerInterceptor接口方法:

2.1 preHandle

代码语言:java
复制
@SuppressWarnings("serial")
public class DispatcherServlet extends FrameworkServlet {
  
  	protected void doDispatch() {
      ...
      if (!mappedHandler.applyPreHandle(processedRequest, response)) {
				return;
			 }
    }
}

最终会调用HandlerInterceptor#preHandle:

代码语言:java
复制
public class HandlerExecutionChain {

  boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
  HandlerInterceptor[] interceptors = getInterceptors();
  if (!ObjectUtils.isEmpty(interceptors)) {
    for (int i = 0; i < interceptors.length; i++) {
      HandlerInterceptor interceptor = interceptors[i];
      if (!interceptor.preHandle(request, response, this.handler)) {
        ...
}

调用所有的HandlerInterceptor拦截器并调用其preHandle方法。

执行controller处理逻辑前执行,返回值为boolean,返回值为true时接着执行postHandle和afterCompletion,若返回false则中断执行。

拦截处理程序的执行。 HandlerMapping确定的适当处理器对象后调用,但在HandlerAdapter调用处理器之前。

DispatcherServlet是在执行链中处理的handler,其中包括了任意数量的拦截器,处理器本身在链的末尾,即最后才处理 handler。 利用该方法,每个拦截器可以决定中止执行链,特别发送一个HTTP错误或写入客户端响应。

异步请求处理参见AsyncHandlerInterceptor 。

true如果执行链应与下一个拦截器或处理程序本身进行。 否则,DispatcherServlet认为,这种拦截器已经处理了响应本身。

在业务处理器处理请求前被调用,只有当该方法返回true,才会继续调用下个InterceptorpreHandle(),若已是最后一个Interceptor,就调用当前请求的Controller

2.2 postHandle

applyPostHandle,获取所有的拦截器并调用其postHandle方法:

代码语言:java
复制
/**
 * Apply postHandle methods of registered interceptors.
 */
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
    throws Exception {

  HandlerInterceptor[] interceptors = getInterceptors();
  if (!ObjectUtils.isEmpty(interceptors)) {
    for (int i = interceptors.length - 1; i >= 0; i--) {
      HandlerInterceptor interceptor = interceptors[i];
      interceptor.postHandle(request, response, this.handler, mv);
    }
  }
}

执行controller的处理后,即业务处理器处理请求执行完成后,并在ModelAndView处理生成视图之前执行。

请求处理后,DispatcherServlet进行视图返回渲染之前进行调用,可在该方法中对Controller处理之后的ModelAndView对象进行操作(如加入公用信息,以便页面显示)。

2.3 afterCompletion

DispatchServlet执行完ModelAndView后执行,即完成之后回调,呈现视图后。 将在处理程序执行的任何结果调用,从而允许适当的资源清理。

需当前对应的InterceptorpreHandle方法的返回值为true时才会执行。该方法将在整个请求结束之后,即DispatcherServlet渲染了对应的视图之后执行,用于资源清理

3 拦截器配置

3.1 针对某种mapping拦截器配置

代码语言:xml
复制
 <bean  
   class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">  
   <property name="interceptors">  
      <list>  
         <ref bean="handlerInterceptor1"/>  
         <ref bean="handlerInterceptor2"/>  
      </list>  
   </property>  
</bean>  
<bean id="handlerInterceptor1"class="springmvc.intercapter.HandlerInterceptor1"/>  
<bean id="handlerInterceptor2"class="springmvc.intercapter.HandlerInterceptor2"/> 

3.2 针对所有mapping配置全局拦截器

代码语言:xml
复制
<!--拦截器 -->  
<mvc:interceptors>  
   <!--多个拦截器,顺序执行 -->  
   <mvc:interceptor>  
      <mvc:mapping path="/**"/>  
      <bean class="com.sss.filter.HandlerInterceptor1"></bean>  
   </mvc:interceptor>  
   <mvc:interceptor>  
      <mvc:mapping path="/**"/>  
      <bean class="com.sss.filter.HandlerInterceptor2"></bean>  
   </mvc:interceptor>  
</mvc:interceptors>  

4 实践

用户访问其他页面时,从Seesion中获取到用户,未登录则重定向到登录页面。

代码语言:java
复制
Public class LoginInterceptor implements HandlerInterceptor {   
    @Override  
    Public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
  
        // 若是登录页面则放行  
        if(request.getRequestURI().indexOf("login.action")>=0){  
            return true;  
        }  
        HttpSession session = request.getSession();  
        //如果用户已登录也放行  
        if(session.getAttribute("user")!=null){  
            return true;  
        }  
        //用户没有登录挑战到登录页面  
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);  
          
        return false;  
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/10/14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 工作原理流程图
  • 2 Spring Web MVC 的处理器拦截器
    • 2.1 preHandle
    • 2.2 postHandle
    • 2.3 afterCompletion
  • 3 拦截器配置
    • 3.1 针对某种mapping拦截器配置
    • 3.2 针对所有mapping配置全局拦截器
  • 4 实践
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档