九、拦截器

拦截器用于拦截控制器方法,它们分别为:

  • 控制器方法执行前拦截
  • 控制器方法执行后拦截
  • 视图渲染之后进行拦截

拦截器的配置

要配置拦截器,首先得定义一个类,让此类继承Spring自带的HandlerInterceptor接口


接口里面有三个抽象方法

  • preHandle:控制器方法执行之前

preHandle它的返回值是:Boolean,目的是为了让网页是否放行

  • postHandle:控制器方法执行之后
  • afterCompletion:在视图渲染之后进行拦截

定义拦截器的时候,需要在springMVC的文件中进行配置,也有三种配置方法:

  • 1 、bean标签配置
  • 2 、ref配置
  • 3 、interceptor配置
<!--bean标签的配置:
		通过找到定义类(拦截器Interceptor),指定该拦截器
		通过bean标签指定的拦截器,作用域为所有地址,即拦截所有地址
-->

<mvc:interceptors>
	<bean class="com.springmvc.interceptors.FirstInterceptor"></bean>
</mvc:interceptors>

<!--ref配置:
		将定义类(拦截器Interceptor)交给spring容器去管理
		再通过ref标签,找到该对象
		其作用域也是为所有地址
-->
<mvc:interceptors>
	<ref bean="firstInterceptor"></ref>
</mvc:interceptors>
<!--interceptor配置:
	可以自定义拦截规则
	它有三个属性:
		mapping:配置拦截的地址
		exclude-mapping:排除拦截的地址
		bean:找到定义类(拦截器Interceptror)
-->
<mvc:interceptors>
	<mvc:interceptor>
    	<mvc:mapping path="/**"></mvc:mapping>
        <mvc:exclude-mapping path="/"></mvc:exclude-mapping>
        <bean class="com.springmvc.interceptors.FirstInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

多个拦截器的执行顺序

preHandle(控制器方法执行前)、postHandle(控制器方法执行后)、afterCompletion(试图渲染之后)的执行顺序:

源码解析:

首先在Controller控制层方法的返回值打断点,它的执行顺序是:

控制器执行方法之前决定是否放行--->ModelAndView(处理模型数据渲染视图并发送返回的页面)--->控制器方法执行后--->视图渲染之后


分别在return、applyPreHandle、mv、PostHandle、processDispatchResult、triggerAfterCompletion打入断点


当页面进行跳转的时:

1 、首先执行的是preHandle、它在控制器方法执行之前执行,控制着页面的放行,是Boolean型,返回值为真:放行,在它的底层源码里面,是获取Interceptor拦截器的长度来递增显示此长度是定义拦截器,并在spring容器中装配的数量最后进行正序显示


2 、当preHandle进行页面的放行后,会将返回的页面交给ModelAndView,让它去实现页面的跳转,接着控制器方法执行之后,它会获取Interceptor拦截器的长度来递减显示所以是反序


**3 、当postHandle执行完之后,紧接着执行tiggerAfterCompletion(视图渲染之后的拦截器),它会获取拦截器的长度,并获取下标idnexOf,根据下标进行递减显示所以是反序 **


总结:

综上所述:

  • 控制器方法执行前的拦截器,是正序显示
  • 执行器方法执行后的拦截器,是反序显示
  • 视图渲染之后的拦截器,是反序显示

若某个拦截器的preHandle返回了false。那么preHandle返回false和它之前的拦截器preHandle都会执行,postHandle都不执行,返回false的拦截器之前的拦截器的afterComplation会执行


十、异常

基于xml的异常处理

SpringMVC提供了一个处理控制器方法执行过程中所出现的异常接口HandlerExceptionResolver

HandlerExceptionResolver接口的实现类有

  • DefaultHandlerExceptionResolver
  • SimpleMappingExceptionResolver

SpringMVC提供了自定义的异常处理器:SimpleMappingExceptionResolver

<!--配置异常处理器-->
<bean class="SimpleMappingExceptionResolver">
	<property name="exceptionMappings">
    	<props>
        	<prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
    <property>
    	<property name="exceptionAttribute" value="ex"></property>
    </property>
</bean>


<!--class:自定义异常处理器
	excepetionMappings:对特定的异常进行映射
	prop-key:映射特定的异常;prop里的内容:出现异常时所跳转的视图名称
	exceptionAttribute:设置一个属性名,value:并将这个属性名的值叫ex,然后把异常信息在请求域中进行共享
-->

基于注解的异常处理

@ControllerAdvice
public class ExceptionController{
    @ExceptionHandler((value = {ArithmeticException.class,NullPointerException.class}){
    public String testEx(Exception ex, Model model){
         model.addAttribute("ex",ex);
         return "error";
       }
    }
}

//@ControllerAdvice:将当前类标识为异常处理的组件
//@ExceptionHandler:用于设置所标识的异常类型
//ex:标识出现的异常,并交给请求域model进行数据共享
error!
<p th:text="${ex}"></p>