拦截器
所有HandlerMapping实现都支持处理程序拦截器,当您要将特定功能应用于某些请求时,这些拦截器非常有用 - 例如,检查主体。拦截器必须实现HandlerInterceptor,实现三种方法,这些方法应该提供足够的灵活性来进行各种预处理和后处理:
- preHandle(…):在执行实际处理程序之前
- postHandle(…):处理程序执行后
- afterCompletion(…):完成请求完成后
要点:
- 基于java反射机制实现的
- 不需要依赖Servlet容器
- 只对Action请求起作用
- 拦截器可以访问action上下文、值栈里的对象
- 在action的生命周期里,拦截器可以多起调用
场景:
- 权限拦截
- 登录拦截
实践:
拦截器:
@Configuration
public class MyInterception implements HandlerInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(MyInterception.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
LOGGER.info("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
LOGGER.info("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
LOGGER.info("afterCompletion");
}
}
拦截器配置:
@Configuration
public class InterceptionConfig extends WebMvcConfigurationSupport {
@Autowired
private MyInterception myInterception;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterception)
.addPathPatterns("/**") // 需要拦截的路径
.excludePathPatterns("/boot/**"); // 放行的路径
}
}
启动容器,观察效果
preHandle
执行真实业务
postHandle
afterCompletion
为什么拦截器不依赖Servlet容器
HandlerInterceptor 和 WebMvcConfigurationSupport包下的,不是javax.servlet包下的
在项目中加入过滤器
@Component
@WebFilter(urlPatterns = "/**", filterName = "myFilter")
public class MyFilter implements Filter {
private static final Logger log = LoggerFactory.getLogger(MyFilter.class);
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 设置编码,身份过滤等代码
log.info("doFilter");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("init");
}
@Override
public void destroy() {
log.info("destroy");
}
}
启动项目,访问接口,控制台输出
init
doFilter
preHandle
执行真实业务
postHandle
afterCompletion
doFilter