SprigMVC拦截器HandlerInterceptor

观前提示:

本文所使用的Eclipse版本为Photon Release (4.8.0),JDK版本为1.8.0_141,Tomcat版本为9.0.12。

1.简介

SpringFramework的处理器拦截器,用于处理器进行预处理和后处理。应用与以下场景:

  1. 日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。

  2. 权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。

  3. 性能监控:典型的是慢日志。

2.拦截器HandlerInterceptor

package org.springframework.web.servlet;

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

public abstract interface HandlerInterceptor
{
  public abstract boolean preHandle(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse, Object paramObject)
    throws Exception;

  public abstract void postHandle(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse, Object paramObject, ModelAndView paramModelAndView)
    throws Exception;

  public abstract void afterCompletion(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse, Object paramObject, Exception paramException)
    throws Exception;
}
  1. preHandle:预处理回调,在处理器处理之前回调。只有该方法返回true,才会继续执行后续的Interceptor和Controller,如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller方法。

  2. postHandle:该方法将在请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用,可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作

  3. afterCompletion:该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。用于进行资源清理。

3.拦截器适配器HandlerInterceptorAdapter

如果实现HandlerInterceptor接口的话,需要全部实现上述的三个方法,但是我们可以通过HandlerInterceptorAdapter,并不需要全部实现,仅需要实现我们所需要的方法即可。

package org.springframework.web.servlet.handler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public abstract class HandlerInterceptorAdapter
  implements AsyncHandlerInterceptor
{
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception
  {
    return true;
  }

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

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

  public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception
  {
  }
}

4.运行流程

4.1 流程1:preHandle处理结果全部为true

返回true
返回true
HandlerInterceptor1.preHandle
HandlerInterceptor2.preHandle
主方法
主方法
HandlerInterceptor2.postHandle
HandlerInterceptor1.postHandle
View渲染
View渲染
HandlerInterceptor2.afterConcurrentHandlingStarted
HandlerInterceptor1.afterConcurrentHandlingStarted

4.2 流程2:preHandle处理结果含有false时

返回true
返回false
HandlerInterceptor1.preHandle
HandlerInterceptor2.preHandle
HandlerInterceptor1.afterConcurrentHandlingStarted

5 例子

配置3个拦截器

<mvc:interceptors>
    <mvc:interceptor>
      <mvc:mapping path="/test"/>
      <bean class="cn.com.mydemo.interceptor.TestHandlerInterceptor1"></bean>
    </mvc:interceptor>
    
    <mvc:interceptor>
      <mvc:mapping path="/test"/>
      <bean class="cn.com.mydemo.interceptor.TestHandlerInterceptor2"></bean>
    </mvc:interceptor>
    
    <mvc:interceptor>
      <mvc:mapping path="/test"/>
      <bean class="cn.com.mydemo.interceptor.TestHandlerInterceptor3"></bean>
    </mvc:interceptor>
  </mvc:interceptors>
package cn.com.mydemo.interceptor;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class TestHandlerInterceptor1 extends HandlerInterceptorAdapter {

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("-----------------afterCompletion1-----------------");
		super.afterCompletion(request, response, handler, ex);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("-----------------postHandle1-----------------");
		super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("-----------------preHandle1-----------------");
		return true;
	}
}
package cn.com.mydemo.interceptor;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class TestHandlerInterceptor2 extends HandlerInterceptorAdapter {

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("-----------------afterCompletion2-----------------");
		super.afterCompletion(request, response, handler, ex);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("-----------------postHandle2-----------------");
		super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("-----------------preHandle2-----------------");
		return true;
	}
}
package cn.com.mydemo.interceptor;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class TestHandlerInterceptor3 extends HandlerInterceptorAdapter {

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("-----------------afterCompletion3-----------------");
		super.afterCompletion(request, response, handler, ex);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("-----------------postHandle3-----------------");
		super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("-----------------preHandle3-----------------");
		return true;
	}
}

主方法

@RequestMapping(value = "/test")
	public void testHandlerInterceptor() {
		System.out.println("-----------------Main Function-----------------");
	}

5.1 3个拦截器preHandle全部返回true

在这里插入图片描述

5.2 3个拦截器preHandle分别返回true,true,false时

在这里插入图片描述

6.总结运行流程

  1. 拦截器按照Spring配置文件中定义的顺序执行。
  2. 会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。
  3. 然后执行主方法(自己的controller接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。
  4. 在主方法执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是页面渲染完数据后,执行after进行清理工作)方法。(postHandle和afterCompletion都是倒序执行)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值