SpringMvc中的Interceptor拦截器拦截请求是通过实现HandlerInterceptor接口来完成的,在SpringMvc中可以自己定义一个HandlerInterceptor的实现类用来拦截请求
HandlerInterceptor中的方法:
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;
void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
preHandle:在请求处理之前被调用,SpringMVC中的Interceptor实行的是链式调用,即在一个应用中或者说一个请求中可以同时存在多个Interceptor。每个Interceptor的调用会依据它的声明顺序依次执行,而且最先执行的是Interceptor中的preHandle方法,当该方法返回true的时候就会继续调用下一个Interceptor的preHandle方法,如果已经是最后一个Interceptor,就会调用当前请求的Controller方法。
postHandle:在当前请求被处理之后,也就是Controller方法被调用之后执行,但是它会在DispatcherServlet进行视图渲染之前被调用。postHandle该方法被调用的方向跟preHandle相反
afterCompletion:该方法将在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行
关于多个Interceptor之间的方法的调用顺序
定义了两个Interceptor,并且注册的顺序是Interceptor1,Interceptor2
1. 1号和2号都放行
测试结果:
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor2...postHandle
HandlerInterceptor1...postHandle
HandlerInterceptor2...afterCompletion
HandlerInterceptor1...afterCompletion
- 1号放行和2号不放行
测试结果:
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor1...afterCompletion
- 1号不放行和2号不放行
测试结果:
HandlerInterceptor1...preHandle
总结
总结:
只有前边的拦截器preHandle方法放行,下边的拦截器的preHandle才执行。
使用拦截器实现用户身份认证的功能
public class UserAuthentificationInterceptor implements HandlerInterceptor {
private static final String[] IGNORE_URL = {"/loginForm.action","/login"};
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...");
/*请求的url:http://localhost:8080/ssmusemaven/loginForm.action
* requestPath的值:/loginForm.action
*请求的url: http://localhost:8080/ssmusemaven/login/admin/123456
* requestPath的值:/login/admin/123456
*/
String requestPath = request.getServletPath();
for(String url : IGNORE_URL){
if(requestPath.contains(url)){
return true;
}
}
if(request.getSession().getAttribute("user")!=null){
return true;
}
request.getRequestDispatcher("/loginForm.action").forward(request, response);
//只有返回true的时候,才会执行下一个interceptor,如果这是最后一个interceptor,那么将会执行controller方法
return false;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
}
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.njust.ssm.interceptor.UserAuthentificationInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
注意
<mvc:mapping path="/**" />
Path=/**:一个*表示只可以拦截一层路径例如/login,两个*表示可以拦截多层路径例如/login/aaa,/login/aaa/bbb/aaa