SpringMVC-拦截器
2020-07-18 本文已影响0人
张明学
SpringMVC提供了两种拦截:HandlerInterceptor和WebRequestInterceptor。HandlerInterceptor可以很清晰知道拦截是Controller的某个方法,从而也可以获取方法上的注解。也可以获取返回的ModelAndView。WebRequestInterceptor获取的WebRequest请求对象和ModelMap结果数据集对象。
实现HandlerInterceptor接口
HandlerInterceptor 接口中定义了三个方法,分别是:preHandle、postHandle、afterCompletion
- preHandle
- 该方法将在请求处理之前进行调用。特点:知道请求的方法
- postHandle
- 当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用。特点:知道返回的ModelAndView
- afterCompletion
- 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。特点:请求结果已返回给前端
public class GlobalInterceptor implements HandlerInterceptor {
/**
* 该方法将在请求处理之前进行调用。特点:知道请求的方法
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
log.info("请求日志#请求方法:{}#{}", handlerMethod.getBean().getClass().getSimpleName(), handlerMethod.getMethod().getName());
}
return true;
}
/**
* 当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用。特点:知道返回的ModelAndView
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
log.info("请求日志#请求结果:{}#{},modelAndView={}", handlerMethod.getBean().getClass().getSimpleName(), handlerMethod.getMethod().getName(), JSON.toJSONString(modelAndView));
}
}
/**
* 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。特点:请求结果已返回给前端
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
log.info("请求日志#请求响流应:{}#{},执行完毕。是否存在异常={}", handlerMethod.getBean().getClass().getSimpleName(), handlerMethod.getMethod().getName(), ex == null ? "无异常" : ex.getMessage());
}
}
}
配置:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="globalInterceptor" class="com.zmx.GlobalInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
多个HandlerInterceptor的配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="globalInterceptor" class="com.zmx.GlobalInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!-- 排除/emp/下的所有请求 -->
<mvc:exclude-mapping path="/emp/**"/>
<bean id="authInterceptor" class="com.zmx.AuthInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
实现WebRequestInterceptor接口
WebRequestInterceptor接口中定义了三个方法,也是preHandle、postHandle、afterCompletion
public class SampleWebRequestInterceptor implements WebRequestInterceptor {
/**
* 该方法将在请求处理之前进行调用,也就是说会在Controller方法调用之前被调用。特点:返回值是void,一般主要用它来进行资源的准备工作
*
*/
@Override
public void preHandle(WebRequest request) throws Exception {
log.info("SampleWebRequestInterceptor#preHandle,参数={}", request.getParameter("key1"));
}
/**
* 该方法将在请求处理之后,也就是在Controller 方法调用之后被调用,但是会在视图返回被渲染之前被调用。特点:可以改变数据模型ModelMap,用来改变数据的展示
*/
@Override
public void postHandle(WebRequest request, ModelMap model) throws Exception {
log.info("SampleWebRequestInterceptor#postHandle");
}
/**
* 方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。特点:在该方法中可以进行资源的释放操作
*/
@Override
public void afterCompletion(WebRequest request, Exception ex) throws Exception {
log.info("SampleWebRequestInterceptor#afterCompletion");
}
}
配置:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="sampleWebRequestInterceptor" class="com.zmx.SampleWebRequestInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
多个拦截器工作流程图
![](https://img.haomeiwen.com/i3626452/947d5824ee37087f.png)