首页 > 编程知识 正文

过滤器和拦截器的区别面试,拦截器和过滤器性能损失

时间:2023-05-04 03:28:30 阅读:17163 作者:1605

过滤器: filter http://www.Sina.com/: filter阻止web服务器管理的所有资源,包括提供URL级别的访问控制和敏感术语过滤。

描述:Filter预处理用户请求,然后将请求传递给servlet进行处理,生成响应,最后Filter对服务器响应进行后处理。

Filter接口包含一个doFilter方法,用于描述我们的业务逻辑并设置阻止哪些资源。 在调用service方法之前,调用Filter的doFilter方法或编写多个Filter。 也可以将这些过滤器组合称为单个过滤器链,以控制调用哪个过滤器,web服务器创建表示过滤器链的过滤器链对象并将其传递给方法。 在doFilter方法中,如果开发人员调用FilterChain对象的doFilter方法,web服务器将检查FilterChain对象是否仍有filter,如果有,则返回第二个filter

public void init (过滤器配置文件配置) /初始化过滤器的创建和销毁由WEB服务器负责。 当web APP应用程式启动时,web伺服器会建立Filter的实体物件,并呼叫其init方法来读取web.xml组态。

完成对象的初始化功能,准备阻止后续的用户请求。 filter对象只创建一次,init方法也只执行一次。

publicvoiddofilter (servletrequestrequest,servlet响应响应,过滤器通道) /此方法完成实际的过滤器操作。 销毁public void destroy () OncePerRequestFilter Spring的OncePerRequestFilter类实际上是实现Filter接口的抽象类。 spring对过滤器进行了一些封装处理,以便在一个请求中只能通过过滤器一次

运行后将在request中设置标识符,因此不需要重复运行。

@ overridepublicfinalvoiddofilter (servletrequestrequest,servlet响应响应,过滤器通道过滤器通道) throwssservletexexponse (responseinstanceofhttpservletresponse () thrownewservletexception (onceperrequestfilterjustsupportshttprequests ' ) ); } httpservletrequesthttprequest=(http servlet请求) request; httpservletresponsehttpresponse=(http servlet响应)响应; //得到起到标记过滤器是否已执行的作用的固定标记。 这就是实现一次操作。 stringalreadyfilteredattributename=getalreadyfilteredattributename (; //检查当前请求是否已经具有此标记,如果有,则过滤器将显示booleanhasalreadyfilteredattribute=request.getattribute (alreadyfilteredattribute )=null; //如果您执行过,或者不直接从拦截范围跳过,则可以使用散列过滤器(http request,if ) request.set attribute (alreadyfilteredattributename,Boolean.TRUE ); 方法try { //是一种抽象方法,需要子类来实现具体的过滤逻辑。 dofilterinternal (http请求,httpResponse,过滤器通道); (finally(/删除此标记。 什么时候运行到这里? request.remove attribute (alreadyfilteredattributename; }}那么,doFilterInternal应该做什么?

publ

ic class xxxx extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain){ //执行业务代码//根据需要是否调用doFilter filterChain.doFilter(requestToUse, response); }}

所以回到上面为什么会在finally里面调用request.removeAttribute() 也就是在请求接口最后,在执行移除标识操作。

拦截器:

SpringBoot之HandlerInterceptorAdapter
在SpringBoot中我们可以使用HandlerInterceptorAdapter这个适配器来实现自己的拦截器。这样就可以拦截所有的请求并做相应的处理。
应用场景:请求日志,权限,JVM性能输出等。

在HandlerInterceptorAdapter中主要提供了以下的方法:

preHandle:在方法被调用前执行。如果返回true,则继续调用下一个拦截器。如果返回false,则中断执行。postHandle:在方法执行后调用。afterCompletion:在整个请求处理完毕后进行回调,也就是调用方已经拿到响应时。 拦截器和过滤器的区别:

拦截器是基于java的反射机制的,而过滤器是基于函数回调。拦截器不依赖与servlet容器,过滤器依赖与servlet容器。拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。拦截器可以获取ioc中的service bean实现业务逻辑,拦截器可以获取ioc中的service
bean实现业务逻辑,在拦截器里注入一个service,可以调用业务逻辑。

触发时机:
过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。
总结:过滤器包裹住servlet,servlet包裹住拦截器

过滤器的触发时机是容器后,servlet之前,所以过滤器的
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
的入参是ServletRequest ,而不是httpservletrequest。因为过滤器是在httpservlet之前。

过滤器

@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ System.out.println("before..."); chain.doFilter(request, response);System.out.println("after...");}

chain.doFilter(request, response);这个方法的调用作为分水岭。事实上调用Servlet的doService()方法是在chain.doFilter(request, response);这个方法中进行的。

2.拦截器是被包裹在过滤器之中的。
拦截器的preHandle()方法是在过滤器的chain.doFilter(request, response)方法的前一步执行,不是doFilter(request,response,chain)之前。
postHandle()方法在return ModelAndView之前,可以操控Controller的内容。
afterCompletion()方法是在过滤器返回给前端前一步执行。也就是doFilter(request,response,chain)方法return之前执行。
在我们项目中用的最多是preHandle这个方法,而未用其他的,框架提供了一个已经实现了拦截器接口的适配器类HandlerInterceptorAdapter,继承这个类重写一下需要用到的方法就行了,可以少几行代码,这种方式Java中很多地方都有体现。

本文摘自:
https://www.cnblogs.com/panxuejun/p/7715917.html
https://www.cnblogs.com/weianlai/p/11358768.html
https://blog.csdn.net/u012554102/article/details/51462161
https://www.cnblogs.com/cainiao-chuanqi/p/11326793.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。