SpringMVC之拦截器
应用场景:登陆验证
HandlerExecutionChain是一个执行链,当请求到达DispatchServlet时,DispatchServlet根据请求路径到HandlerMapping查询具体的Handler,从HandlerMapping返回给DispatcherServlet,其中包含了一个具体的Handler对象和Interceptors(拦截器集合)。
如何自定义拦截器:
springmvc的拦截器接口(HandlerInterceptor)定义了三个方法:
-
preHandle
调用Handler之前执行,称为前置方法
返回值:true表示放行,后续业务逻辑继续执行。
返回值:false表示被拦截,后续业务逻辑不再执行,但之前返回true的拦截器的完成方法会倒叙执行
-
postHandle
调用Handler之后执行,称为后置方法
-
afterCompletion
视图渲染完成之后执行
拦截器的执行过程
MyInterceptor.java
package com.deng.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
/**
* 前置方法,在Handler执行方法之前执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle...");
return true;
}
/**
* 后置方法,在Handler执行方法之后执行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
/**
* 完成方法,在视图渲染完成之后执行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion...");
}
}
MyInterceptor2.java
package com.deng.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor2 implements HandlerInterceptor {
/**
* 前置方法,在Handler执行方法之前执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("preHandle2...");
return true;
}
/**
* 后置方法,在Handler执行方法之后执行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle2...");
}
/**
* 完成方法,在视图渲染完成之后执行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion2...");
}
}
springmvc.xml
<!-- 配置自定义拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截所有controller请求,包括多级路径也能被拦截
例如:/hello.do /hello/show1.do都能被拦截 -->
<mvc:mapping path="/**"/>
<!-- 自定义拦截器的全路径名 -->
<bean class="com.deng.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 拦截所有请求(多级路径) -->
<mvc:mapping path="/**"/>
<!-- 自定义拦截器的全路径名 -->
<bean class="com.deng.interceptor.MyInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
拦截前
把MyInterceptor2中preHandle方法的返回值改为false,表示拦截器拦截了请求,不放行,直接返回
拦截后
结论:
- 拦截器的前置方法依次执行,后置方法和完成方法倒序执行
- 当前置方法返回false时,后续的拦截器以及Handler方法不再执行,但它前序的前置方法返回true的拦截器的完成方法会倒续执行。
- 完成方法会在视图渲染完成之后才去执行。