SpringMVC拦截器

拦截器

过滤器过滤的是客户端对资源的访问

拦截器的配置

SpringMVC中的拦截器用于拦截控制器方法的执行

SpringMVC的拦截器需要实现HandlerInterceptor

SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置:


        
        
        
        
        
        
            
            
            
    
/** 
 * 拦截器的三个方法:
 * preHandle():在控制器方法执行之前执行,其返回值表示对控制器方法的拦截(false) 或放行(true)
 * postHandle():在控制器方法执行之后执行
 * afterCompletion():在控制器方法执行之后,且渲染视图完毕之后执行 在render()之后执行,
 *
 * 多个拦截器执行顺序和在SpringMVC的配置文件中配置的顺序有关
 * preHandle()按照配置的顺序执行,而postHandle()和afterCompletion按照配置的反序执行
 */
@Component
public class FirstInterceptor implements HandlerInterceptor {
​
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 控制器方法执行之前执行 true 放行 false 拦截
        System.out.println("FirstInterceptor-->preHandle");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
​
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor-->postHandle");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }
​
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor-->afterCompletion");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

异常处理器


    
        
            
            error
        
    
    
    

处理器 == 控制器方法

applyPreHandle()源码

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
        HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
        if (!interceptor.preHandle(request, response, this.handler)) {
            this.triggerAfterCompletion(request, response, (Exception)null);
            return false;
        }
    }
​
    return true;
}

applyPostHandle()源码

void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
    for(int i = this.interceptorList.size() - 1; i >= 0; --i) {
        HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
        interceptor.postHandle(request, response, this.handler, mv);
    }
​
}

triggerAfterCompletion源码

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {
    for(int i = this.interceptorIndex; i >= 0; --i) {
        HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
​
        try {
            interceptor.afterCompletion(request, response, this.handler, ex);
        } catch (Throwable var7) {
            logger.error("HandlerInterceptor.afterCompletion threw exception", var7);
        }
    }
​
}

根据观察源码我们可以知道为什么preHandle()按照配置的顺序执行,而postHandle()和afterCompletion按照配置的反序执行。

因为在源码中applyPreHandle()遍历时用的是i++,而applyPostHandle()和triggerAfterCompletion()中用的是i--,

若拦截器中有某个拦截器的preHandle()返回了false

  • 拦截器的preHandle()返回了false和它之前的拦截器都会执行 之后的不会执行

  • 所有拦截器的postHandle()都不执行

  • 拦截器的preHandle()返回了false之前的拦截器的afterCompletion()会执行

异常处理器

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

Handler ExceptionResovler接口的实现类又:DefaultHandlerExceptionResolver 和 SimpleMappingExceptionResolver

SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResovler,使用方式:

XML


    
        
            
            error
        
    
    
    

注解:

// 将当前类标识为异常处理的组件
@ControllerAdvice
public class ExceptionController {
​
    // 设置要处理的异常信息
    @ExceptionHandler(ArithmeticException.class)
    public String handleException(Throwable ex, Model model){
        // ex标识控制器方法所出现的异常
        model.addAttribute("ex", ex);
        return "error";
    }
​
}

你可能感兴趣的:(spring,java,后端)