简单了解一下过滤器和拦截器:
过滤器是servlet规范中的一部分,任何java
web工程都可以使用;在url-pattern中配置/*之后,可以对所有要访问的资源拦截。拦截器是springMVC框架自己的一部分,只有使用springMVC框架的工程才能用;拦截器只会拦截控制器方法,即Controller中的方法,访问jsp,HTML,css,image,js是不会进行拦截的。
springMVC的拦截器,作用于Controller方法执行前后,通过实现org.springframework.web.servlet.HandlerInterceptor
接口来实现。
接口中有三个方法:preHandle
作用于Controller方法调用之前,预处理;postHandle
作用于Controller方法调用之后,后处理;afterCompletion
顾名思义作用于页面模板引擎加载完成过后,主要用于一些资源回收工作。
preHandle
方法有返回值,当返回false时,将不会执行Controller方法,也就不会进入到目标的页面去。可以通过方法参数中的httpServletRequest
做请求转发。
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
return false;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
下面简单为实现拦截器的操作步骤:
- 编写Controller
和普通的控制器方法无差,在方法中输出一段语句,后面可根据控制台打印结果查看相关方法的执行顺序。
@Controller
public class TestInterceptorController {
@RequestMapping("/testInterceptor")
public String testInterceptor(){
System.out.println("testInterceptor...");
return "success";
}
}
- 编写拦截器
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("preHandle...");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion...");
}
}
- 配置拦截器
除了配置包扫描、注解驱动、视图解析器外,这里需要配置拦截器,将拦截器和控制器方法关联起来。如果存在多个拦截器需要配置,在<mvc:interceptors>
标签下再添加多个<mvc:interceptor>
单元模块即可。如果针对同一个控制器方法,有多个拦截器,会按照配置的先后顺序执行。
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/testInterceptor"/>
<bean class="com.wuwl.interceptor.TestInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
- 编写前端页面
简单的超链接即可。
<a href="testInterceptor">testInterceptor</a>
- 编写成功页面
这里我们在jsp页面加一句后台输出,可以看到拦截器执行的顺序。
<p>you success</p>
<%
System.out.println("loading jsp success");
%>
- 启动tomcat,测试demo
- 查看控制台输出
这里我们可以清楚的看到,添加拦截器过后,访问/testInterceptor
请求时,先来到拦截器的preHandle方法,做预处理;返回true后,执行控制器方法,方法返回的字符串;执行拦截器的postHandle方法,做后处理;同时视图解析器根据返回的字符串进行拼接,指向跳转页面;页面加载完成后,须再执行拦截器的afterCompletion方法,进行相关资源的回收。
preHandle...
testInterceptor...
postHandle...
loading jsp success
afterCompletion...
注:如果存在多个拦截器拦截同一个请求,这里演示两个,我们将拦截器的输出语句加上编号。这样最后控制台的输出语句将变成:
preHandle111...
preHandle222...
testInterceptor...
postHandle222...
postHandle111...
loading jsp success
afterCompletion222...
afterCompletion111...
postHandle
和afterCompletion
执行的顺序和preHandle
的顺序是相反的,这个顺序来自原springmvc.xml
配置拦截器的先后顺序。