SpringMVC —— 第十四章 SprinMVC 拦截器
1. 拦截器(interceptor
)的作用
SpringMVC 的 拦截器 类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行 预处理 和 后处理 。
将拦截器按一定的顺序联结成一条链,这条链称为 拦截器链(Interceptor Chain
) 。在访问被拦截的方法或者字段时,拦截器链中的的拦截器就会按其之前定义的顺序被调用。拦截器也是 AOP思想 的具体实现。
2. 拦截器和过滤器的区别
区别 | 过滤器(Filter) | 拦截器(Intercepter) |
---|---|---|
使用范围 | 时 Servlet 的一部分,任何 Java Web 工程都可以使用 | 时 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能使用 |
拦截范围 | 在 url-pattern 中设置了 /* 之后,可以对所有要访问的资源进行拦截 |
在 <mvc:mapping path = "" /> 中设置了 /** 之后,也可以对所有资源进行拦截,但是可以通过 <mvc:exclude-mapping path = "" /> 标签排除不需要拦截的资源 |
3. 拦截器的快速入门
自定义拦截器的步骤:
- 创建拦截器类实现
HandlerInterceptor
接口 - 在
spring-mvc.xml
中配置拦截器 - 测试拦截器的拦截效果
示例代码:
com.yourname.controller.TargetController
/**
* @author gregPerlinLi
* @since 2021-09-09
*/
@Controller
public class TargetController {
@RequestMapping(value = "/target")
public ModelAndView show() {
System.out.println("Target resource executing...");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name", "gregperlinli");
modelAndView.setViewName("index.jsp");
return modelAndView;
}
}
com.yourname.interceptor.MyInterceptor
/**
* @author gregPerlinLi
* @since 2021-09-09
*/
public class MyInterceptor implements HandlerInterceptor {
/**
* Execute before the target method executes
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("PreHandle...");
// Returning true means release, and returning false means no release
String param = request.getParameter("param");
if ( "yes".equals(param) ) {
return true;
} else {
request.getRequestDispatcher("/error.jsp").forward(request, response);
return false;
}
// return HandlerInterceptor.super.preHandle(request, response, handler);
}
/**
* After the target method is executed, the view is executed before it returns
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("PostHandle...");
modelAndView.addObject("name", "gregPerlinLi");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* Execute after the whole process is executed
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("AfterCompletion...");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
com.yourame.interceptor.MyInterceptor2
/**
* @author gregPerlinLi
* @since 2021-09-09
*/
public class MyInterceptor2 implements HandlerInterceptor {
/**
* Execute before the target method executes
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("PreHandle2...");
// Returning true means release, and returning false means no release
String param = request.getParameter("param");
if ( "yes".equals(param) ) {
return true;
} else {
request.getRequestDispatcher("/error.jsp").forward(request, response);
return false;
}
// return HandlerInterceptor.super.preHandle(request, response, handler);
}
/**
* After the target method is executed, the view is executed before it returns
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("PostHandle2...");
modelAndView.addObject("name", "gregPerlinLi");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* Execute after the whole process is executed
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("AfterCompletion2...");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
spring-mvc.xml
<mvc:interceptors>
<mvc:interceptor>
<!-- Which resources are intercepted -->
<mvc:mapping path="/**"/>
<bean class="com.gregperlinli.interceptor.MyInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.gregperlinli.interceptor.MyInterceptor2" />
</mvc:interceptor>
</mvc:interceptors>
4. 拦截器方法说明
方法名 | 说明 |
---|---|
preHandle() |
方法将在请求处理之前进行调用,该方法的返回值是布尔值 Boolean 类型的,当它返回 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当返回值为 true 时会继续调用下一个 Interceptor 的 preHandle 方法 |
psotHandle() |
该方法是在当前请求进行处理之后被调用,前提是 preHandle 方法的返回值为 true 时才能被调用,且它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以我们在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作 |
afterCompletion() |
该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行,前提是 preHandle 方法返回值为 true 时才能被调用 |
5. 知识要点
自定义拦截器步骤
- 创建拦截器类实现
HandlerInterceptor
接口 - 在
spring-mvc.xml
中配置拦截器 - 测试拦截器的拦截效果