当前位置: 移动技术网 > IT编程>开发语言>Java > 在spring-boot工程中添加spring mvc拦截器

在spring-boot工程中添加spring mvc拦截器

2019年07月19日  | 移动技术网IT编程  | 我要评论
1. 认识拦截器 spring mvc的拦截器(interceptor)不是filter,同样可以实现请求的预处理、后处理。使用拦截器仅需要两个步骤: 实现

1. 认识拦截器

spring mvc的拦截器(interceptor)不是filter,同样可以实现请求的预处理、后处理。使用拦截器仅需要两个步骤:

  • 实现拦截器
  • 注册拦截器

1.1 实现拦截器

实现拦截器可以自定义实现handlerinterceptor接口,也可以通过继承handlerinterceptoradapter类,后者是前者的实现类。下面是拦截器的一个实现的例子,目的是判断用户是否登录。如果prehandle方法return true,则继续后续处理。

public class logininterceptor extends handlerinterceptoradapter {
/**
*预处理回调方法,实现处理器的预处理(如登录检查)。
*第三个参数为响应的处理器,即controller。
*返回true,表示继续流程,调用下一个拦截器或者处理器。
*返回false,表示流程中断,通过response产生响应。
*/
@override
public boolean prehandle(httpservletrequest request, httpservletresponse response, 
object handler) throws exception {
system.out.println("-------------------prehandle");
// 验证用户是否登陆
object obj = request.getsession().getattribute("username");
if (obj == null || !(obj instanceof string)) {
response.sendredirect(request.getcontextpath() + "/");
return false;
}
return true;
}
/**
*当前请求进行处理之后,也就是controller 方法调用之后执行,
*但是它会在dispatcherservlet 进行视图返回渲染之前被调用。
*此时我们可以通过modelandview对模型数据进行处理或对视图进行处理。
*/
@override
public void posthandle(httpservletrequest request, httpservletresponse response, 
object handler, modelandview modelandview) throws exception {
system.out.println("-------------------posthandle");
}
/**
*方法将在整个请求结束之后,也就是在dispatcherservlet 渲染了对应的视图之后执行。
*这个方法的主要作用是用于进行资源清理工作的。
*/
@override
public void aftercompletion(httpservletrequest request, httpservletresponse response, 
object handler, exception ex) throws exception {
system.out.println("-------------------aftercompletion");
}
}

1.2 注册拦截器

为了使自定义的拦截器生效,需要注册拦截器到spring容器中,具体的做法是继承webmvcconfigureradapter类,覆盖其addinterceptors(interceptorregistry registry)方法。最后别忘了把bean注册到spring容器中,可以选择@component 或者 @configuration。

@component
public class interceptorconfiguration extends webmvcconfigureradapter{
@override
public void addinterceptors(interceptorregistry registry) {
// 注册拦截器
interceptorregistration ir = registry.addinterceptor(new logininterceptor());
// 配置拦截的路径
ir.addpathpatterns("/**");
// 配置不拦截的路径
ir.excludepathpatterns("/**.html");
// 还可以在这里注册其它的拦截器
//registry.addinterceptor(new otherinterceptor()).addpathpatterns("/**");
}
}

1.3 拦截器的应用场景

拦截器本质上是面向切面编程(aop),符合横切关注点的功能都可以放在拦截器中来实现,主要的应用场景包括:

  1. 登录验证,判断用户是否登录。
  2. 权限验证,判断用户是否有权限访问资源。
  3. 日志记录,记录请求日志,以便统计请求访问量。
  4. 处理cookie、本地化、国际化、主题等。
  5. 性能监控,监控请求处理时长等。

2. 原理

2.1 工作原理

拦截器不是filter,却实现了filter的功能,其原理在于:

  • 所有的拦截器(interceptor)和处理器(handler)都注册在handlermapping中。
  • spring mvc中所有的请求都是由dispatcherservlet分发的。
  • 当请求进入dispatcherservlet.dodispatch()时候,首先会得到处理该请求的handler(即controller中对应的方法)以及所有拦截该请求的拦截器。拦截器就是在这里被调用开始工作的。

2.2 拦截器工作流程

一个拦截器,只有prehandle方法返回true,posthandle、aftercompletion才有可能被执行;如果prehandle方法返回false,则该拦截器的posthandle、aftercompletion必然不会被执行。

假设我们有两个拦截器,例如叫interceptor1和interceptor2,当一个请求过来,正常的流程和中断的流程分别如下。

2.2.1正常流程
注意两个拦截器在执行prehandle方法和执行posthandle、aftercompletion方法时,顺序是颠倒的。

  1.  interceptor1.prehandle
  2. interceptor2.prehandle
  3.  controller处理请求
  4. interceptor2.posthandle
  5. interceptor1.posthandle
  6. 渲染视图
  7.  interceptor2.aftercompletion
  8.  interceptor1.aftercompletion

2.2.2 中断流程

假设执行interceptor2.prehandle中报错,那么流程被中断,之前被执行过的拦截器的aftercompletion仍然会执行。在本例中,即执行了interceptor1.aftercompletion。

1. interceptor1.prehandle
2. interceptor2.prehandle
//中间流程被中断,不再执行
3. interceptor1.aftercompletion

2.3 和filter共存时的执行顺序

拦截器是在dispatcherservlet这个servlet中执行的,因此所有的请求最先进入filter,最后离开filter。其顺序如下。

filter->interceptor.prehandle->handler->interceptor.posthandle->interceptor.aftercompletion->filter

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网