- 过滤器(Filter)
依赖于 Servlet 容器(所以不能应用 spring 容器的资源)
实现是基于函数回调
能够对所有申请进行过滤 - 拦截器(Intercepter)
依赖于 web 容器(能够应用 spring 容器的资源)
实现是基于反射
只能对 controller 申请进行拦挡,对间接拜访动态资源的申请无奈拦挡
执行程序
Filter 前解决 ->Intercepteor 前解决 ->action->Interceptor 后处理 ->Filter 后处理
Filter 的作用
- 在 HttpServletRequest 达到 Servlet 之前,查看,批改甚至拦挡 HttpServletRequest。
- 在 HttpServletResponse 达到客户端之前,批改或拦挡 HttpServletResponse。
- 检查用户申请,依据申请过滤用户非法申请。
- 具体记录某些非凡的用户申请。
- 对非标准编码的申请解码
Inteceptor 的作用
- 日志记录:记录申请信息的日志,以便进行信息监控、信息统计、计算 PV(Page View)等;
- 权限查看:如登录检测,进入处理器检测是否登录;
- 性能监控:通过拦截器在进入处理器之前记录开始工夫,在解决完后记录完结工夫,从而失去该申请的解决工夫。(反向代理,如 Apache 也能够自动记录)
- 通用行为:读取 Cookie 失去用户信息并将用户对象放入申请,从而不便后续流程应用,还有如提取 Locale、Theme 信息等,只有是多个处理器都须要的即可应用拦截器实现
javax.servlet.Filter 接口:
- void init(FilterConfig config):Filter 的初始化。
- void destory():Filter 销毁前,资源的回收。
- void doFilter(ServletRequest request,ServletResponse response,FilterChain chain): 在调用 chain.doFilter()办法前能够对 request 进行预处理,在调用 chain.doFilter()办法后能够对 response 进行后处理
HandlerInterceptor 接口:
-
preHandle 在申请解决之前进行调用。能够在这个办法中进行初始化或预处理或判断来决定申请是否要持续进行上来。
- 返回值为 true 时示意继续执行,会持续调用下一个 Interceptor 的 preHandle 办法,如果曾经是最初一个 Interceptor 的时候就会是调用以后申请的 Controller 办法
- 返回为 false 时,示意申请完结,后续的 Interceptor 和 Controller 都不会再执行
- postHandle preHandle 办法的返回值为 true 时能力被调用 postHandle 办法,Controller 办法调用之后执行,然而它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以咱们能够在这个办法中对 Controller 解决之后的 ModelAndView 对象进行操作
- afterCompletion 在整个申请完结之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行。这个办法的次要作用是用于进行资源清理工作的。
Filter 实现
public class MyFilter1 implements Filter {private static final Logger logger = LoggerFactory.getLogger(MyFilter1.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {logger.info("***************MyFilter1 init******************");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {logger.info("------------MyFilter1-doFilter before---------");
logger.info("-------" + request.getRemoteAddr() + ":" +request.getRemotePort() + "--------");
String usrId = request.getParameter("usrId");
if((usrId == null)||(usrId.isEmpty())||(Integer.parseInt(usrId)<=0)) {HttpServletResponse httpResponse = (HttpServletResponse)response;
httpResponse.getWriter().print("Parameter error!");
} else if(Integer.parseInt(usrId) >=1000) {chain.doFilter(request, response);
}
logger.info("------------MyFilter1-doFilter after---------");
}
@Override
public void destroy() {logger.info("***************MyFilter1 destroy******************");
}
}
Interceptor 实现
public class LogInterceptor implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
@Autowired
UserPrivilegeService privilegeService;
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {logger.info("*********** LogInterceptor preHandle *******************");
long startTime = System.currentTimeMillis();
httpServletRequest.setAttribute("startTime", startTime);
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {logger.info("*********** LogInterceptor postHandle *******************");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {logger.info("*********** LogInterceptor afterCompletion *******************");
long startTime = (Long) httpServletRequest.getAttribute("startTime");
long endTime = System.currentTimeMillis();
logger.info("End Time:" + endTime);
logger.info("Time Taken:" + (endTime - startTime));
}
}
增加 Filter
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean1(){FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new MyFilter1());
bean.addUrlPatterns("/login");
bean.setOrder(1); // 值越小优先级越高
return bean;
}
}
增加 Interceptor
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LogInterceptor());
}
}
测试代码