过滤器
Filter 是 Servlet 的一种工具,用于对 web 服务器管理的 web 资源(例如Jsp, Servlet, 静态图片文件或静态 html 文件等 )进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。思想是过滤器模式(责任链模式)。
实现方式:
1、实现 javax.servlet.Filter 接口,并实现方法;
@Slf4j
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("initFilter----------------");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("doFilter----------------");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
log.info("destroyFilter----------------");
}
}
2、注入到 servlet 容器
- 如果用的是外置的 tomcat 容器,直接在 webapp/web.xml 中添加 filter 映射即可
<filter>
<filter-name>TestFilter </filter-name>
<filter-class>TestFilter 权限定类名</filter-class>
</filter>
<!--映射过滤器-->
<filter-mapping>
<filter-name>TestFilter </filter-name>
<!--“/*”表示拦截所有的请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
- 如果用 SpringBoot 的内嵌 tomcat 容器,是没有 web.xml 的,需要在配置类中添加
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean testFilter(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>(new TestFilter());
return filterRegistrationBean;
}
}
监听器
Servlet 中用于对系统的域对象产生、销毁,绑定等进行监听的组件,
Servlet监听器分为三大类
1、ServletContextListener : 用来监听ServletContext对象的创建和销毁
2、HttpSessionListener: HttpSession 数据对象创建和销毁监听器
3、ServletRequestListener: HttpServletRequest对象的创建和销毁监听器
Servlet监听器详解及举例
拦截器
通常,拦截器是指 SpringMvc 中的 拦截器,用于拦截请求,从而做一些处理。
实现 SpringMvc 拦截器:
- 实现 HandlerInterceptor, 或者继承 HandlerInterceptorAdapter,实现方法;
题外话:
HandlerInterceptorAdapter 是 HandlerInterceptor 的抽象实现类,目的就是为了避免开发拦截器,需要重写所有的的 HandlerInterceptor 方法;
但是 java 从 1.8 开始,接口支持 default 方法,即接口内部也可以有方法实现,下面是 HandlerInterceptor 的源码:
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
所以,在实现 HandlerInterceptor 的时候,可以只重写自己关注的方法,其他方法则可以不用实现,这样一来,HandlerInterceptorAdapter 貌似就没啥用了。同样的情况也出现在上面的 WebMvcConfigurer 和 WebMvcConfigurerAdapter 等很多这样类似的组合,所以很多 XXXAdapter 都已经被标注为过时。
实现:
public class TestInterceptor implements HandlerInterceptor {
//在请求发生前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(true){
//放行
return true;
}else{
//终端请求
return false;
}
}
/**
*在Controller的方法调用之后,在DispatcherServlet进行视图的渲染之前,可以对ModelAndView进行操作
*前提是 preHandle 返回 true
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
*DispatcherServlet进行视图的渲染之后,多用于清理资源
*前提是 preHandle 返回 true
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
- 在 WebMvcConfigurer 中重写 addInterceptors(), 将拦截器加入到 registry
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean testFilter(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>(new TestFilter());
return filterRegistrationBean;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor())
.addPathPatterns("/*","/**")
.excludePathPatterns("/abc");
}
}
三者对比
对比 | 过滤器 | 监听器 | 拦截器 |
---|---|---|---|
依赖于 | Servlet | Servlet | SpringMvc |
针对 | Web请求 | 系统域对象的监听 | Web请求 |
实现方式 | 函数回调 | 事件触发 | 动态代理 |
另外,拦截器和过滤器还有几点不通
1.拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里得任何资源、对象,例如Service对象、数据源、事务管理等,通过Ioc注入道拦截器即可。而Filter则不能。
网友评论