转载自:
拦截器(Interceptor) 同 Filter(过滤器) 一样,它俩都是面向切面编程——AOP 的具体实现(AOP切面编程只是一种编程思想而已)。
你可以使用 Interceptor 来执行某些任务,例如在 Controller 处理请求之前编写日志,添加或更新配置…
在 Spring中,当请求发送到 Controller 时,在被Controller处理之前,它必须经过 Interceptors(0或更多)。
Spring Interceptor是一个非常类似于Servlet Filter 的概念 。
过滤器和拦截器的区别
对于过滤器和拦截器的区别:
- **过滤器(Filter):**当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。
- **拦截器(Interceptor):**在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。
自定义 Interceptor
如果你需要自定义 Interceptor 的话必须实现 org.springframework.web.servlet.HandlerInterceptor接口或继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter类,并且需要重写下面下面3个方法:
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler)
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView)
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex)
注意: ***preHandle***方法返回 true或 false。如果返回 true,则意味着请求将继续到达 Controller 被处理。
LogInterceptor
用于过滤所有请求
OldLoginInterceptor
是一个拦截器,如果用户输入已经被废弃的链接 /admin/oldLogin
,它将重定向到新的 /admin/login
**AdminInterceptor
**用于拦截请求路径为 /admin/*
下的请求
配置拦截器:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// LogInterceptor apply to all URLs.
registry.addInterceptor(new LogInterceptor());
// Old Login url, no longer use.
// Use OldURLInterceptor to redirect to a new URL.
registry.addInterceptor(new OldLoginInterceptor())
.addPathPatterns("/admin/oldLogin");
// This interceptor apply to URL like /admin/*
// Exclude /admin/oldLogin
registry.addInterceptor(new AdminInterceptor())
.addPathPatterns("/admin/*")
.excludePathPatterns("/admin/oldLogin");
}
}
结合自定义 Controller 验证拦截器,完成测试,具体请看源码:https://gitee.com/mikeLv01/security-interceptor-demo.git
注意:该实例需要引入 thymeleaf 的依赖,否则报错
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
结果:
测试用户访问 http://localhost:8080/ 的时候, LogInterceptor记录相关信息(页面地址,访问时间),并计算 Web服务器处理请求的时间。另外,页面会被渲染成 test.html
。
当用户访问 http://localhost:8080/admin/oldLogin 也就是旧的登录页面(不再使用)时, OldLoginInterceptor将请求重定向 http://localhost:8080/admin/login 页面会被渲染成正常的登录页面 login.html
。
Request URL: http://localhost:8088/admin/oldLogin
Start Time: 1586184588848
-------- OldLoginInterceptor.preHandle ---
Request URL: http://localhost:8088/admin/oldLogin
Sorry! This URL is no longer used, Redirect to /admin/login
-------- LogInterception.afterCompletion ---
Request URL: http://localhost:8088/admin/oldLogin
End Time: 1586184588849
Time Taken: 1
Request URL: http://localhost:8088/admin/login
Start Time: 1586184588857
-------- AdminInterceptor.preHandle ---
-------- MainController.login ---
** You are in Controller **
-------- AdminInterceptor.postHandle ---
-------- LogInterception.postHandle ---
Request URL: http://localhost:8088/admin/login
-------- AdminInterceptor.afterCompletion ---
-------- LogInterception.afterCompletion ---
Request URL: http://localhost:8088/admin/login
End Time: 1586184588860
Time Taken: 3