【java面试100问】75 过滤器和拦截器有什么区别?

文摘   2025-01-10 07:27   天津  

 

首先,从原理上讲,过滤器(Filter)是基于函数回调的,而拦截器(Interceptor)则是基于Java的反射机制(动态代理)实现的。

简单来说,过滤器就像是你在处理请求和响应之前或之后加的一个钩子,而拦截器则是通过反射机制在请求处理流程中的特定位置插入了一些额外的逻辑。

在使用范围上,过滤器依赖于Servlet容器(如Tomcat),只能在Web程序中使用。

而拦截器是一个Spring组件,由Spring容器管理,并不依赖Servlet容器,可以单独使用,不仅能应用在Web程序中,也可以用于Application、Swing等程序中。

从拦截请求的范围来看,过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中的请求或访问static目录下的资源请求起作用。

这意味着,过滤器的应用范围更广,而拦截器更专注于对Controller层的请求进行拦截和处理。

在触发时机上,过滤器在请求进入容器后,但在进入Servlet之前进行预处理,请求结束是在Servlet处理完以后。

拦截器则是在请求进入Servlet后,在进入Controller之前进行预处理的,Controller中渲染了对应的视图之后请求结束。

在注入Bean的情况上,拦截器在Spring context之前加载,由于加载顺序的问题,拦截器无法直接注入Spring管理的Bean。

而过滤器则没有这个限制,可以直接注入Bean。

控制执行顺序上,过滤器可以通过@Order注解控制执行顺序,值越小级别越高越先执行。

拦截器默认的执行顺序是它的注册顺序,也可以通过Order手动设置控制,值越小越先执行。但需要注意的是,过滤器的执行顺序在拦截器之前。

下面,我将通过一个简单的示例来展示过滤器和拦截器的实际应用。

过滤器示例

假设我们要实现一个简单的过滤器,用于记录每次请求的URI。

public classMyFilterimplementsFilter {
    @Override
    publicvoidinit(FilterConfig filterConfig)throws ServletException {
    }

    @Override
    publicvoiddoFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {
        HttpServletRequestrequest= (HttpServletRequest) servletRequest;
        StringrequestURI= request.getRequestURI();
        System.out.println("拦截到请求: " + requestURI);

        filterChain.doFilter(request, servletResponse);
    }

    @Override
    publicvoiddestroy() {
    }
}

然后,在web.xml中配置这个过滤器:

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这样,每当有请求进入容器时,这个过滤器就会被触发,记录请求的URI。

拦截器示例

接下来,我们实现一个简单的拦截器,用于检查用户是否登录。

public classLoginInterceptorimplementsHandlerInterceptor {
    @Override
    publicbooleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
        HttpSessionsession= request.getSession();
        if (session.getAttribute("user") == null) {
            response.getWriter().write("用户未登录");
            returnfalse;
        }
        returntrue;
    }
}

然后,在Spring配置类中注册这个拦截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
    }
}

这样,每当有请求进入Controller之前,这个拦截器就会被触发,检查用户是否登录。

如果用户未登录,则直接返回“用户未登录”的响应,不再继续执行后续的Controller方法。

通过上面的讲解和示例,相信你对过滤器和拦截器的区别有了更深入的理解。

在实际开发中,你可以根据具体的需求选择合适的工具来实现你的功能。


希望文章能给大家带来点技术收获。也希望大家能够点赞收藏转发,让知识成为大家的财富。你的支持,是我最大的动力!

  

你诺喜欢,请点个关注

大家可以发送消息:202501

领取计算机黑皮书191本(1月有效)

每晚8:30分享VIP资源

扫码加个人V拉你进群(备注IT资源)


推荐文章:

推荐java面试100题讲解源文件


夏壹分享
系统化技术讲解,每日精进,为后端技术人员打造的知识充电站!
 最新文章