Spring拦截器

28 篇文章 0 订阅
10 篇文章 0 订阅

工作原理

  • Spring Interceptor依赖于 IOC容器, 基于 Java反射机制动态代理实现的

执行顺序

  • 过滤前 - 拦截前 - Action处理 - 拦截后 -过滤后

使用场景

  • 拦截器常用于权限验证等场景, 但由于依赖 IOC容器, 因此比起过滤器更灵活, 且控制的更细

常用拦截器接口

名称类型-
HandlerInterceptor接口Spring的基础拦截器
AsyncHandlerInterceptor接口继承 HandlerInterceptor接口, 并多了 afterConcurrentHandlingStarted方法, 用于处理异步请求
HandlerInterceptorAdapter抽象类实现 AsyncHandlerInterceptor接口的适配器类
WebRequestInterceptor接口类似与 HandlerInterceptor接口, 不同在于此接口只针对请求, 所以没有 response参数, 还有 preHandle没有返回值

HandlerInterceptor例子

工作流程

  • 首先执行 preHandle方法(请求Controllor之前), 如果返回值是 true将会执行 postHandle方法(请求Controllor之后视图渲染之前), 最后执行 afterCompletion. 或当 preHandle方法的返回值为 false将会终止当前拦截器, 并如果下一步还有相同条件下的一个或多个拦截器都会终止, 还有如有当前拦截器之前有已执行过的拦截器也都不会不行到 postHandle方法, 而直接执行 afterCompletion结束拦截器, 但当前拦截器是不会执行 afterCompletion.

import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomHandlerInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("CustomHandlerInterceptor preHandle");
        return true;
    }

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

	/**
	* 用于给当前拦截器做资源清理
	*/
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        System.out.println("CustomHandlerInterceptor afterCompletion");
    }

}

AsyncHandlerInterceptor例子

工作流程

  • 与 HandlerInterceptor接口类似, 不过多了 afterConcurrentHandlingStarted方法, 当执行 preHandle方法的返回值是 false时以及没有异步请求时是与 HandlerInterceptor接口完全相同, 或 preHandle方法的返回值是 true, 且处理异步请求时 会执行 afterConcurrentHandlingStarted方法, 请看输出日志

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

public class CustomAsyncHandlerInterceptor implements AsyncHandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("CustomAsyncHandlerInterceptor preHandle");
        return true;
    }

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

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

    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("CustomAsyncHandlerInterceptor afterConcurrentHandlingStarted");
    }

}

# 测试地址 http://127.0.0.1:8080/streaming
@GetMapping(value = "/streaming")
public StreamingResponseBody streaming() {
	System.out.println("TestController -> streaming");
	return (OutputStream outputStream) -> {
		outputStream.write("streaming: ".getBytes());
		outputStream.flush();
		outputStream.close();
	};
}

# 输出日志
CustomHandlerInterceptor preHandle
CustomAsyncHandlerInterceptor preHandle
TestController -> streaming
CustomAsyncHandlerInterceptor afterConcurrentHandlingStarted
CustomHandlerInterceptor preHandle
CustomAsyncHandlerInterceptor preHandle
CustomAsyncHandlerInterceptor postHandle
CustomHandlerInterceptor postHandle
CustomAsyncHandlerInterceptor afterCompletion
CustomHandlerInterceptor afterCompletion

HandlerInterceptorAdapter例子

工作流程

  • 与 AsyncHandlerInterceptor接口完全相同, 只不过此接口为适配器, 因此可以只覆写要用的方法, 如果当前用的 Java版本是1.8的话由于出了新特性 default, 基本与实现 AsyncHandlerInterceptor接口相同了

WebRequestInterceptor例子

工作流程

  • 方法的执行顺序与 HandlerInterceptor接口相同, 不同在于此接口只针对请求, 所以没有 response参数, 还有 preHandle没有返回值

import org.springframework.lang.Nullable;
import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;

public class CustomWebRequestInterceptor implements WebRequestInterceptor {
    public void preHandle(WebRequest var1) throws Exception {
        System.out.println("CustomWebRequestInterceptor preHandle");
    }

    public void postHandle(WebRequest var1, @Nullable ModelMap var2) throws Exception {
        System.out.println("CustomWebRequestInterceptor postHandle");
    }

    public void afterCompletion(WebRequest var1, @Nullable Exception var2) throws Exception {
        System.out.println("CustomWebRequestInterceptor afterCompletion");
    }

}

配置拦截器

  • Spring5.x或 Spring boot2.x版本或以上版本, 配环境时实现 WebMvcConfigurer, 以下版本可以实现 WebMvcConfigurerAdapter
    通配符|匹配范围
    –|:–:
    *| 如 /user/* 将会匹配 /user/a | /user/abc
    ** | 包括多级路径 如 /user/** 将会匹配 /user/a | /user/abc/list | /user/abc/list/name等
    ABC*| 如 /user/list* 将会匹配 /user/list | /user/lists等

import com.example.demo.interceptor.CustomAsyncHandlerInterceptor;
import com.example.demo.interceptor.CustomHandlerInterceptor;
import com.example.demo.interceptor.CustomWebRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;

@Configuration
public class WebConfig implements WebMvcConfigurer {
	/**
	* 添加拦截器方法 addInterceptor
	* 添加请求地址条件方法 addPathPatterns
	* 添加过滤请求条件方法 excludePathPatterns
	*/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customHandlerInterceptor()).addPathPatterns("/*");
        registry.addInterceptor(customAsyncHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/streaming");
        registry.addInterceptor(customWebRequestInterceptor()).addPathPatterns("/*/list*");
    }

    @Bean
    public CustomHandlerInterceptor customHandlerInterceptor() {
        return new CustomHandlerInterceptor();
    }

    @Bean
    public CustomAsyncHandlerInterceptor customAsyncHandlerInterceptor() {
        return new CustomAsyncHandlerInterceptor();
    }

    @Bean
    public WebRequestHandlerInterceptorAdapter customWebRequestInterceptor() {
        return new WebRequestHandlerInterceptorAdapter(
                new CustomWebRequestInterceptor()
        );
    }

}

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值