1.基本概念
拦截器是AOP面向切面编程的应用,即代理。它通过指定切入点在其前后进行代码增强以达到简化公共代码以及实现拦截和过滤的作用。拦截器链是将拦截器按照一定的顺序连接,在访问被拦截的字段或方法的时候,拦截器链中的拦截器会按照其之前定义的顺序被使用。
拦截器和过滤器都是进行增强的实现,它们看起来功能类似,但也有如下区别:
1) 过滤器是servlet规范中的一部分,任何java web工程都可以正常使用。但拦截器是SpringMVC框架自己开发的,只能在SpringMVC框架下的工程才可以使用。
2) 过滤器在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截。拦截器只会拦截访问的控制器方法,如果访问的是jsp,html,css,image和js等静态资源文件是不会进行拦截的。所以后者的拦截必须使用过滤器。
我们要自定义拦截器必须实现HandlerInterceptor接口。
2.使用
2.1 编写拦截器类
必须实现HandlerInterceptor接口:
package nju.software.utils.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 MyInterceptor1 implements HandlerInterceptor {
/**
* 预处理,controller之前执行
* return true 放行,执行下一个拦截器,如果没有执行controller中的方法
* return false 不放行,拒绝执行方法。
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle.");
//拦截器预处理也可以不放行,并跳转到执行页面
//如果return true加跳转,最终会跳转到preHandle指定的页面,但controller也会执行,会加载controller的页面又跳回来
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
// return true;
return true;
}
/**
* 后处理方法,在controller方法执行后,在success.jsp的页面加载执行前
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);效果同上
System.out.println("postHandle.");
}
/**
* 最后方法,在success.jsp方法执行后再执行
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/5097fa8adb353463bec77345229632e3.png)
2.2 配置拦截器类
springmvc.xml文件:
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置需要拦截的方法,通过访问的url来配置-->
<mvc:mapping path="/interceptor/*"/>
<!-- 配置不拦截的方法 <mvc:exclude-mapping path=""/>-->
<!-- 配置拦截器对象 也可以配置在interceptors标签下,作为公共拦截器-->
<bean id="myInterceptor1" class="nju.software.utils.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
</mvc:interceptors>
2.3 拦截器链
拦截器链的工作方式是预处理先配置先执行,后处理和最终处理后配置先执行,执行时机相同:
举例在springmvc.xml文件的配置顺序:
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置需要拦截的方法,通过访问的url来配置-->
<mvc:mapping path="/interceptor/*"/>
<!-- 配置不拦截的方法 <mvc:exclude-mapping path=""/>-->
<!-- 配置拦截器对象-->
<bean id="myInterceptor1" class="nju.software.utils.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 配置需要拦截的方法,通过访问的url来配置
/**表示拦截一切访问
-->
<mvc:mapping path="/**"/>
<!-- 配置不拦截的方法 <mvc:exclude-mapping path=""/>-->
<!-- 配置拦截器对象-->
<bean id="myInterceptor2" class="nju.software.utils.interceptor.MyInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
最终执行结果如下: