目录
lerInterceptor 拦截器
1、拦截器的作用
2、拦截器的创建
3、拦截器的三个抽象方法
4、拦截器的配置
5、多个拦截器的执行顺序
SpringMVC的异常处理器
1、异常处理器概述
2、基于配置文件的异常处理
3、基于注解的异常处理
lerInterceptor 拦截器
1、拦截器的作用
拦截器的作用时机
SpringMVC的拦截器作用于
控制器方法执行的前后
。有不同的拦截方法,作用于控制器方法执行之前、之后、以及视图渲染之后三个阶段
拦截器与过滤器的区别
过滤器是原生Serlvet的组件,作用于Servlet执行之前
拦截器是SpringMVC的模块,作用于控制器方法执行前、后、渲染视图后。
2、拦截器的创建
SpringMVC中的拦截器需要实现HandlerInterceptor接口
示例
public class FirstInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("控制器方法准备执行...");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("控制器方法执行完毕...");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("视图渲染完毕...");}}
3、拦截器的三个抽象方法
HandlerInterceptor接口有三个抽象方法:
- preHandle:
控制器方法执行之前
执行preHandle(),其boolean类型的返回值表示是否拦截或放行
返回true为放行,即调用控制器方法
;返回false表示拦截,即不调用控制器方法
- postHandle:
控制器方法执行之后
执行postHandle()- afterComplation:处理完视图和模型数据,
渲染视图完毕之后
执行afterComplation()
源码分析,为什么preHandle能实现拦截控制器方法
//DispatherServletif (!mappedHandler.applyPreHandle(processedRequest, response)) {//如果applyPreHandle方法返回的是false,就直接return,不再执行下面的内容return;}//执行控制器方法mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//渲染视图...//applyPreHandle方法boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {for (int i = 0; i < this.interceptorList.size(); i++) {HandlerInterceptor interceptor = this.interceptorList.get(i);if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);//如果当前拦截器的preHandle方法返回false,applyPreHandle方法也返回falsereturn false;}this.interceptorIndex = i;}return true;}
注意
SpringMVC配置文件中的
view-controller视图控制器标签,也会被拦截器拦截
。
4、拦截器的配置
SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置。
拦截器有三种配置方式,一般使用第三种,可以配置拦截范围。
方式一在interceptors中配置
自定义拦截器的bean标签
这种方式
无法指定拦截范围
,是对DispatcherServlet所处理的所有的请求进行拦截
方式二在interceptors中引用
自定义拦截器的bean id
和上面一样,这种方式
无法指定拦截范围
,是对DispatcherServlet所处理的所有的请求进行拦截
配置自定义拦截器的bean时,可以使用配置文件,也可以使用@Component注解+组件扫描的方式
方式三使用标签进行配置
可以配置三个属性:
- mapping:
拦截请求的请求地址
,可以使用Ant风格的路径- exclude-mapping:
不会被拦截的请求地址
,即拦截白名单- bean/ref:指定拦截器的bean
例如这里是拦截所有请求,不拦截testInterceptor页面,对应的拦截器是firstInterceptor
5、多个拦截器的执行顺序
如果匹配到的多个拦截器的preHandle()方法都返回true
此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:
preHandle()
会按照配置的顺序执行,即先配置的先执行
postHandle()和afterComplation()
会按照配置的反序执行,即先配置的后执行
,因为是嵌套的关系。示例,请求访问,匹配到一个控制器方法,两个拦截器:
配置顺序:
执行顺序:
preHandle A –> true
preHandle B –> true
— 控制器方法执行 —
— 控制器方法执行完毕 —
postHandle B
postHandle A
— 视图渲染完毕 —
afterComplation B
afterComplation A
如果匹配到多个拦截器,有的拦截器的preHandle()方法返回了false
先看结果:对于同一个控制器方法,只要存在拦截器的preHandle()方法返回了false,控制器方法就不会执行。
- 在它之前配置的拦截器,和它自己的preHandle()都会执行
- 所有的postHandle()都不执行,因为控制器方法没有执行
- 在它之前配置的拦截器,afterComplation()会执行
- 在它之后配置的拦截器,所有方法都不会执行。
示例 请求访问,匹配到一个控制器方法,两个拦截器,其中一个返回false:
配置顺序:
Interceptor B 的preHandle()返回false
执行顺序:
preHandle A –> true
preHandle B –> false
— 控制器方法不执行 —
afterComplation A
SpringMVC的异常处理器
1、异常处理器概述
异常处理器的作用
用于处理SpringMVC 控制器方法执行过程中 产生的异常。
SpringMVC提供了一个处理 控制器方法执行过程中所出现的异常的接口:
HandlerExceptionResolver
HandlerExceptionResolver接口的实现类:
- DefaultHandlerExceptionResolver,是SpringMVC默认使用的异常处理器
- SimpleMappingExceptionResolver,用于自定义 异常处理器
自定义异常处理器的使用场景
大致有两个作用:
- 对系统异常提供自定义处理。比如出现某个异常时,跳转到服务器繁忙的页面,用户就不会看到500这类的页面了
- 提供对自定义异常的处理方案
2、基于配置文件的异常处理
SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver
示例 实现错误页面跳转
error
properties的键表示处理器方法执行过程中出现的异常
properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面
测试
error页面
服务器繁忙!
控制器方法
@RequestMapping("/testInterceptor")public String testInterceptor(){//创造一个数学异常Integer i = 3/0;return "success";}
发生异常后,就会被自定义的异常处理器捕获,跳转到错误页面
示例 实现异常信息的捕获
配置文件
error
配置exceptionAttribute属性,设置一个value
异常信息就会存入request域中,键名为设置的value,值为异常信息。
前端页面展示错误信息
服务器繁忙!
3、基于注解的异常处理
使用注解,实现获取异常信息和跳转错误页面
@ControllerAdvicepublic class ExceptionController {@ExceptionHandler(value = {ArithmeticException.class})public String testException(Exception exception, Model model){model.addAttribute("exception", exception);return "error";}}
原理:如果遇到了@ExceptionHandler 注解 标识的这些异常,就调用 此 @ExceptionHandler 注解对应的控制器方法。
使用注解,在配置文件中就不需要配置任何关于异常处理器的内容。