SpringMVC学习笔记(四)-异常处理与拦截器
异常处理
- Spring将异常层层传导,从dao、service、controller直到前端控制器中,此时若前端控制器没有配置异常处理机制,将会把异常输出到页面
- 在异常处理器中集中处理异常,使用
@ExceptionHandler
- @ExceptionHandler:放置于方法上,表示该方法可以处理某个类型的异常,当出现该异常时调用对应方法,处理异常的方法与控制器方法使用方式一致
- @ControllerAdvice:放置于类上,表明这是一个拥有异常处理方法的类,给控制器增强异常处理的功能,AOP的思想实现业务与非业务功能的分离
@ControllerAdvice
public class MyExceptionHandler{
@ExcepionHandler(value={MyException.class})
//不配置value属性,则会匹配其他异常
public ModelAndView doMyExeptionHandler(Exception e){
... ...
}
//此方法返回的结果为用户接受的最终结果
}
- 记住配置组件扫描器与注解驱动
拦截器
- 概念:
- SpringMVC框架中的一种对象,需要实现接口HandlerInterceptor
- 拦截用户请求对请求进行预处理与后处理,可将controller中共用的功能定义至拦截器
- 拦截器分为:系统拦截器与自定义拦截器、可设置多个拦截器
- 常用于登陆检查、权限验证、统计数据... ...
- 使用:
- 自定义拦截器实现HandlerInterceptor接口,其存在三个默认方法
- preHandle()为预处理方法,参数
Object handler
为配拦截的控制器对象,返回值为false时请求立即阶段,不会再执行后续的拦截器方法及控制器方法
- 在设置的控制器方法之前执行
- postHandle()为后处理方法,参数ModelAndView modelAndView为控制器方法的返回值
- 在设置的控制器方法之后执行,可用于改变原执行结果,可修改数据或视图
- afterCompletion,参数Object handler为拦截的处理器, Exception ex方法执行过程中抛出的异常
- 所有请求处理完成之后执行,释放资源或进行清理
- 方法执行的条件:
- 当前拦截器preHandle()方法必须执行
- preHandle()必须返回true
- 声明拦截器
<mvc:interceptors>
<!--声明一个拦截器-->
<mvc:interceptor>
<!--指定拦截器的拦截地址,path:拦截的uri地址,使用**通配符可以匹配多地址-->
<mvc:mapping path="/user/**"/>
<!--指定使用的拦截器-->
<bean id="xxx" class="xxx.xxx.xxx"/>
</mvc:interceptor>
</mvc:interceptors>
多拦截器
- 多拦截器的执行顺序:同一拦截路径下,mvc配置文件中配置的顺序即为拦截器的执行顺序
- 在内层拦截器的预处理返回结果为false是,拦截器链截断,但外层afterCompletion可以执行
- 在外层拦截器预处理结果为false,内层为true时,不会进入内层
- 多层拦截器的意义:
- 将验证分散至多个独立的拦截器,每个拦截器执行单一的验证处理
- 多个拦截器,串于一个链条上,多个拦截器和一个控制器对象置于一个链条上,框架使用HandlerExecutionChain表示执行链
- 通过遍历HandlerExecutionChain实现拦截器的依次执行
- 拦截器与过滤器的对比:
- 拦截器是SpringMVC框架中的对象,过滤器是Servlet中的对象
- 拦截器对象由框架创建,过滤器由Tomcat创建
- 拦截器侧重于对请求进行判断处理,可以截断请求,过滤器侧重于对request,response对象的属性,参数进行设置。
- 拦截器存在三个执行时间,过滤器在请求之前
- 拦截器用于拦截对控制器的请求,过滤器可以拦截所有动态静态资源
- 当拦截器与过滤器一起执行时,先执行过滤器,之后为前端控制器,最后为拦截器
SpringMVC的执行流程
- 用户请求交予DispatcherServlet统一调度
- DispatcherServlet将请求交予处理器映射器(实现了HandlerMapping,从容器中获取控制器对象)处理后将控制器与拦截器放入执行链中返回至DispatcherServlet
- DispatcherServlet将获取的控制器对象交予处理器适配器(实现HandlerAdapter接口,用于执行控制器中的方法)获得结果
- DispatcherServlet将执行结果交予视图解析器(实现ViewResolver接口,处理视图组成视图的完整路径,能创建完整的View类型结果)
- DispatcherServlet调用View类中的方法将Model中的数据放入Request作用域中,对视图执行转发