Spring Mvc 拦截器详解

目录

 一、什么是拦截器

二、拦截器配置

三、定义拦截器

四、 多个拦截器


 一、什么是拦截器

Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。

所有 HandlerMapping 的实现都支持 handler 拦截器,当你想对某些请求应用特定的功能时,这些拦截器是非常有用的—​例如,检查一个 principal。拦截器必须实现 org.springframework.web.servlet 包中的 HandlerInterceptor,它有三个方法,应该可以提供足够的灵活性来进行各种预处理和后处理:

  • preHandle(..): 在实际 handler 运行之前

  • postHandle(..): handler 运行后

  • afterCompletion(..): 在整个请求完成后

preHandle(..) 方法返回一个boolean值。你可以使用这个方法来中断或继续执行链的处理。当这个方法返回 true 时,handler 执行链继续进行。当它返回 false 时, DispatcherServlet 认为拦截器本身已经处理了请求(例如,渲染了一个适当的视图),并且不继续执行其他拦截器和执行链中的实际 handler。

postHandle 方法在 @ResponseBody 和 ResponseEntity 方法中用处不大,因为这些方法的响应是在 HandlerAdapter 中和 postHandle 之前写入和提交的。这意味着对响应进行任何修改都太晚了,比如添加一个额外的 header。

二、拦截器配置

在Java配置中,你可以注册拦截器来应用于传入的请求,如下例所示:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LocaleChangeInterceptor());
        registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
    }
}

下面的例子显示了如何在XML中实现同样的配置:


    
    
        
        
        
    

 映射的拦截器并不适合作为安全层,因为它有可能与注解的控制器路径匹配不匹配,它也可以透明地匹配尾部斜线和路径扩展,以及其他路径匹配选项。这些选项中的许多已经被废弃,但错配的可能性仍然存在。一般来说,我们推荐使用Spring Security,它包括一个专门的 MvcRequestMatcher,与Spring MVC的路径匹配保持一致,同时还有一个安全防火墙(security firewall),可以阻止URL路径中许多不需要的字符。

三、定义拦截器

package com.doker.interceptor;

public class MyInterceptor implements HandlerInterceptor { 

/** * 预处理,controller 方法执行前 * 应用:用于身份认证、身份授权 * return true 放行,执行下一个拦截器,如果没有,执行 controller 中的方法 * return false 不放行,即不向下执行 */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 

System.out.println("preHandle");
return true;
}
/** * 后处理方法,controller 方法执行后,方法跳转 success.jsp 执行之前 * 应用:从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图 */
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 

System.out.println("postHandle");
}
/** * success.jsp 页面执行后,该方法会执行 * 应用:统一异常处理,统一日志处理 */
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 

System.out.println("afterCompletion");
}
}

四、 多个拦截器

  • 多个拦截器时,按照 springmvc.xml 配置的顺序执行。
  • (2个拦截器时) 拦截器1 preHandle 不放行,postHandle 和 afterCompletion 不会执行。
  • (2个拦截器时) 拦截器1 preHandle 不放行,拦截器2不执行。

    
        
        
        
        
        
        
    
 
    
        
        
        
    

所以,多个拦截器是按照配置的顺序决定的:handlerInterceptorDemo1—>handlerInterceptorDemo2。

你可能感兴趣的:(#,Spring,专栏,spring,mvc,java)