SpringBoot2.X学习之Intercepter拦截器

本文详细介绍了SpringBoot 2.0及之前版本的拦截器实现方式,包括旧版配置和新版配置的具体步骤,对比了Filter与Interceptor的区别。

本节课对SpringBoot2.0以及之前版本的拦截器进行讲解

在SpringBoot1.x的版本中实现拦截器,首先写一个自定义拦截器实现addInterceptors接口,实现其三个方法:

package com.qzsun.springbootdemo.intecpter;

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

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

public class LoginIntercepter implements HandlerInterceptor{

	/**
	 * 进入controller方法之前
	 */
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		System.out.println("LoginIntercepter------->preHandle");

//		String token = request.getParameter("access_token");
//
//		response.getWriter().print("fail");

		return HandlerInterceptor.super.preHandle(request, response, handler);
	}

	/**
	 * 调用完controller之后,视图渲染之前
	 */
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

		System.out.println("LoginIntercepter------->postHandle");

		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}

	/**
	 * 整个完成之后,通常用于资源清理
	 */
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("LoginIntercepter------->afterCompletion");

		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}



}

然后写一个配置类继承WebMvcConfigurerAdapter,然后重写其addInterceptors()方法,并将刚刚写的拦截器注册进去,并加上拦截规则:

package com.qzsun.springbootdemo.intecpter;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * @author sunqizheng
 * @Title: CustomOldWebMvcConfigurer
 * @ProjectName springbootdemo
 * @Description: 2.0版本之前拦截器,方法过时了
 * @date 2019/1/3113:34
 */
//@Configuration
public class CustomOldWebMvcConfigurer extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/");
        super.addInterceptors(registry);
    }
}

但是该写法在2.0版本中已经过时了,我们点进源码查看发现其已被@Deprecated掉了,原因在源码的注释上已经写清楚了:

@deprecated从Spring5.0开始{@link WebMvcConfigurer}具有默认方法(由Java 8基线实现),可以直接实现而无需此适配器

 

下面我们进行新版本拦截器的实现,第一步也是写一个自定义拦截器,就沿用刚刚写的拦截器,然后写一个配置类实现WebMvcConfigurer接口,重写addInterceptors()方法,注意加上注解@Configuration纳入容器管理,然后在里面注册之前写好的LoginIntercepter,然后加上拦截路径,注意:如果是拦截所有的话就是"/**",拦截器最后如果是路径的话一定要 “/**”, 如果是目录的话则是 /*/:

/**
 * @author sunqizheng
 * @Title: CustomWebMvcConfigurer
 * @ProjectName springbootdemo
 * @Description: 拦截器配置,类似于以前mvc项目的Spring配置文件中配置拦截器
 * @date 2019/1/3113:57
 */
@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截器最后路径一定要 “/**”, 如果是目录的话则是 /*/
        //如果是拦截所有的话就是"/**"
        registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/*/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

然后在controller中加一个接口供测试使用:

@RequestMapping("/api/test/intercepter")
    public String intercepter(){
        System.out.println("--------测试拦截器-----");
        return "index";
    }

启动并访问http://localhost:8081/api/test/intercepter

拦截器起作用了, preHandle()在进入controller方法之前调用,postHandle()在调用完controller之后,视图渲染之前调用

,afterCompletion()在整个请求完成之后,通常用于资源清理

如果是两个拦截器,他们的顺序是先定义的先拦截,下面我们再自定义一个拦截器,并注册到配置类中:

package com.qzsun.springbootdemo.intecpter;

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

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

public class TwoIntercepter implements HandlerInterceptor{

	/**
	 * 进入对应的controller方法之前
	 */
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {

		System.out.println("TwoIntercepter------>preHandle");
		return HandlerInterceptor.super.preHandle(request, response, handler);
	}

	/**
	 * controller处理之后,返回对应的视图之前
	 */
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("TwoIntercepter------>postHandle");
		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}

	/**
	 * 整个请求结束后调用,视图渲染后,主要用于资源的清理
	 */
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("TwoIntercepter------>afterCompletion");
		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}

	
}
@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截器最后路径一定要 “/**”, 如果是目录的话则是 /*/
        //如果是拦截所有的话就是"/**"
        registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/*/**");
        registry.addInterceptor(new TwoIntercepter()).addPathPatterns("/api/*/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

 启动运行,我们发现果真是先定义的先执行,但是在执行完handle方法之后就是先定义的后执行了,就像两个同心圆,handle方法在最里面,外面一层是拦截器2,最外面一层是拦截器1。

 补充:我们可以使用.excludePathPatterns()方法排除掉不需要拦截的路径:

Filter与Intercepter的区别:

Filter
        是基于函数回调 doFilter(),而Interceptor则是基于AOP思想
        Filter在只在Servlet前后起作用,而Interceptor够深入到方法前后、异常抛出前后等

        依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境。
    
        在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。
        
        Filter和Interceptor的执行顺序
         
        过滤前->拦截前->action执行->拦截后->过滤后

源码地址:https://gitee.com/xuxinsunqizheng/SpringBoot2.0.git  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值