重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
1. 认识拦截器
创新互联建站-专业网站定制、快速模板网站建设、高性价比爱辉网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式爱辉网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖爱辉地区。费用合理售后完善,十多年实体公司更值得信赖。
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() + "/index.html"); 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),符合横切关注点的功能都可以放在拦截器中来实现,主要的应用场景包括:
2. 原理
2.1 工作原理
拦截器不是Filter,却实现了Filter的功能,其原理在于:
2.2 拦截器工作流程
一个拦截器,只有preHandle方法返回true,postHandle、afterCompletion才有可能被执行;如果preHandle方法返回false,则该拦截器的postHandle、afterCompletion必然不会被执行。
假设我们有两个拦截器,例如叫Interceptor1和Interceptor2,当一个请求过来,正常的流程和中断的流程分别如下。
2.2.1正常流程
注意两个拦截器在执行preHandle方法和执行postHandle、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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。