因为filter问题导致DispatcherServlet执行两次或者多次调用,原理分析

在搭建前台组件化框架过程中,启动程序时发现一个页面请求但是DispatcherServlet执行了多次, 如图:

因为filter问题导致DispatcherServlet执行两次或者多次调用,原理分析

页面返回了三倍,但是页面请求只有一次,如图:

因为filter问题导致DispatcherServlet执行两次或者多次调用,原理分析

后台日志:

因为filter问题导致DispatcherServlet执行两次或者多次调用,原理分析

后来经过各种排查各种调试之后发现原因是过滤器的链调用放在了循环中:

因为filter问题导致DispatcherServlet执行两次或者多次调用,原理分析

链调用放循环外就好了,如图:

因为filter问题导致DispatcherServlet执行两次或者多次调用,原理分析

现在来分析原理,因为新建了一个过滤器来做前端相关操作预处理,采用实现javax.servlet.Filter接口的方式,所以需要手动链式调用,因为我循环调用了chain.doFilter(request, response); 相当于执行了多个filter链,但是对于页面请求其实只有一次,而造成多个结果一次返回,有些同学可能会有疑问,觉得页面应该会被覆盖掉,应该只有一次结果展示在页面,那么就得说说filter和servlet的关系了:

过滤器的作用,对从客户端向服务器端发送的请求进行过滤,也可以对服务器端返回的响应进行处理。它使用户可以改变一个request和修改一个 response.。Filter 不是一个servlet,它不能产生一个response,但是它能够在一个request到达servlet之前预处理request,也可以在 response离开servlet时处理response。换句话说,filter其实是客户端与servlet中间的一个传递者,并且它可以对要传递 的东西进行修改。

因为filter问题导致DispatcherServlet执行两次或者多次调用,原理分析

 注意:过滤器是用来拦截请求和响应的,不能产生响应,而servlet是用来处理请求视图渲染并产生响应的。

过滤器建议,建议用继承OncePerRequestFilter的方式避免实现Filter接口来实现