这是我前不久面试遇到的问题。当时,我惊呆了。两人被挑出来了。虽然他们不完整,但他们大概知道请求可以被拦截并一起比较。头痛。其实之前面试完就去研究了一波,只是当时没有及时总结。现在总结一下,免得以后忘记这类问题。理解这种题,当时光靠背可能有用,但过一段时间就忘得差不多了。要真正记住,我们必须练习它。Filter的使用首先,要使用Filter,必须实现javax.servlet.Filter接口:publicinterfaceFilter{//将web应用加载到容器中。Filter对象创建后,执行init方法初始化加载资源,只执行一次。publicdefaultvoidinit(FilterConfigfilterConfig)throwsServletException{}//每次拦截请求或响应时执行,可以执行多次。publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException;//web应用移除容器,服务器正常关闭,然后执行destroy方法释放资源,只执行一次。publicdefaultvoiddestroy(){}}init和destroy是默认方法,实现类不需要实现。必须实现doFilter,即作为过滤器,必须定义doFilter。doFlilter方法中传入的FilterChain对象用于调用下一个过滤器。拦截器的使用publicinterfaceHandlerInterceptor{//拦截handler的执行-->HanlerMapping确定合适的handler后,【在HandlerAdater调用handler之前执行。]defaultbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{returntrue;}//拦截handler的执行-->[在HandlerAdapter调用handler之后],在DispatcherServlet渲染视图之前执行defaultvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,@NullableModelAndViewmodelAndView)throwsException{}//视图渲染后调用,只有preHandle的结果为真,才会调用defaultvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,@NullableExceptionex)throwsException{}}//DispatcherServletif(!mappedHandler.applyPreHandle(processedRequest)nse);response){//遍历所有拦截器,调用preHandle方法,只返回true才继续}//这里是处理Controllermv=ha.handle(processedRequest,response,mappedHandler.getHandler());//视图渲染applyDefaultViewName(processedRequest,mv);//视图渲染完成后调用mappedHandler.applyPostHandle(processedRequest,response,mv);过滤器和拦截器有什么区别?1.实现原理不同过滤器的实现是基于基于Java的反射机制[动态代理]的回调函数拦截器实现的。2.使用范围不同Filters是Servlet规范,需要实现javax.servlet.Filter接口。Filters的使用依赖于Tomcat等容器。拦截器是一个Spring组件,定义在org.springframework.web.servlet包下,由Spring容器管理【有更丰富的生命周期处理方式,细粒度,可以使用Spring中的资源】,不依赖在Tomcat和其他容器上。3、触发时机不同。这一段可以在HandlerInterceptor类的注释中找到。两者的触发时机不同:Filter:在进入Servlet之前或之后处理请求。拦截器:处理处理程序[Controller]前后的请求。四、执行顺序不同同时配置过滤器和拦截器:MyFilter1beforeMyFilter2andMyInterceptor1beforeControllerMyInterceptor2beforeController执行controller方法执行...MyInterceptor2Controller之后,视图渲染之前MyInterceptor1Controller之后,在视图渲染之前MyInterceptor2view渲染完成后,执行MyInterceptor1。视图渲染完成后,执行MyFilter2。MyFilter1之后,filter的顺序每次都会传入chain对象,达到最终接口回调的效果:拦截器顺序preHandle1->preHande2->【Controller】->postHandle2->postHandle1->afterCompletion2->afterCompletion1preHandle遵循注册顺序,后两者与注册顺序相反。如果一个拦截器的preHandle为false,那么后面的所有拦截器都不会被执行。如果拦截器的preHandle为真,则执行该拦截器的triggerAfterCompletion。PostHandle只有在所有拦截器preHandlers都为true时才会执行,也就是正常执行。booleanapplyPreHandle(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{HandlerInterceptor[]interceptors=getInterceptors();if(!ObjectUtils.isEmpty(interceptors)){for(inti=0;i
