过滤器和拦截器的辨析

这篇具有很好参考价值的文章主要介绍了过滤器和拦截器的辨析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

过滤器和拦截器的辨析

介绍

过滤器和拦截器都是为了在请求到达目标处理器(Servlet或Controller)之前或者之后插入自定义的处理逻辑

  • 过滤器:

遵循AOP(面向切面编程)思想实现,基于Servlet规范提供的Filter接口,它是位于客户端请求与服务器响应之间的一个组件,依赖于Servlet容器。当请求到达服务器时,过滤器会在请求进入实际目标资源(如Servlet、JSP页面)之前或之后执行特定的操作,原理是基于函数回调

  • 拦截器

遵循AOP(面向切面编程)思想实现,如Spring MVC中的HandlerInterceptor接口,它不依赖于Servlet容器的具体实现,而是由应用框架管理。拦截器是在请求进入到控制器层(Controller)方法前后执行自定义逻辑

原理解析

过滤器

为什么说过滤器基于函数回调?

过滤器基于函数回调,所谓函数回调/回调函数指的是:一个函数(称为回调函数)作为参数传递给另一个函数(称为调用函数),当满足一定条件或者在某个特定时刻,调用函数会调用传递过来的回调函数

由于Java中不直接支持函数指针,所以常常通过接口来实现回调机制

FilterChain就是一个接口

public interface FilterChain {

    public void doFilter(ServletRequest request, ServletResponse response)
            throws IOException, ServletException;

}

Filter的实现类中doFilter()方法中FilterChain作为参数被传进来,并且在合适的时机被回调了其doFilter方法

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("hello");
        chain.doFilter(request,response);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

拦截器

拦截器基于AOP(面向切面编程)思想实现,但是并不一定用到动态代理或者切面,切点之类的技术,以如Spring MVC中的HandlerInterceptor接口为例,从源码看更像是直接将拦截器注入,形成了一个拦截器链,在controller层面上进行代码织入

DispatcherServlet作为SpringMVC框架的核心类,http请求的核心执行方法为doService(),再进入doDispatch()方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
        /**
         * 1.
         * HandlerExecutionChain 是一个对象
         * 包含了以下重要的属性
         * private final Object handler; //处理器(controller和其最后的方法)
         * List<HandlerInterceptor> interceptorList = new ArrayList<>();//拦截器列表,用来存储匹配处理器的拦截器
         */
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

                /**
                 * 2.
                 * 下面这行代码 大概做了以下事情
                 * 1.通过request和url 匹配了对应的controller以及调用的方法 填充了HandlerExecutionChain.handler
                 * 2.通过匹配request和HandlerInterceptor的注册信息(拦截哪些,放行哪些),往HandlerExecutionChain.interceptorList中添加对应的拦截器
                 */
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
					noHandlerFound(processedRequest, response);
					return;
				}

				// Determine handler adapter for the current request.
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				// Process last-modified header, if supported by the handler.
				String method = request.getMethod();
				boolean isGet = HttpMethod.GET.matches(method);
				if (isGet || HttpMethod.HEAD.matches(method)) {
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
						return;
					}
				}
                /**
                 * 3.执行 拦截器链条中的所有前置方法
                 */
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

                /**
                 * 4.交由处理器(controller对应的方法)去处理方法中的业务逻辑
                 */
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				if (asyncManager.isConcurrentHandlingStarted()) {
					return;
				}

				applyDefaultViewName(processedRequest, mv);
                
                /**
                 * 5.倒序执行 拦截器链条中的所有后置方法
                 */
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}}
        //...

流程解析

由于Filter依赖于Servlet容器所以不同的容器Filter,FilterChain的实现类存在差异,这里以Tomcat为例分析

1.向后台发起一次请求

2.接待线程接收到,将任务转交给工作线程

3.判断协议,封装必要对象

4.将request,response一路转交至StandardWrapperValve.invoke(Request request, Response response)

5.创建过滤链ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);

​ 5.1从上下文中获取注册好的过滤器

​ 5.2遍历过滤器,匹配URL,Servlet等,将匹配好的过滤器加入到过滤器链

6.依次回调FilterChain的doFilter方法filterChain.doFilter(request.getRequest(),response.getResponse());

7.将所有过滤器的前置代码执行完毕,进入servlet,servlet.service(request, response);

8.进入DispatcherServlet统一调度

9.调用拦截器前置方法

10.进入controller中的对应方法,执行具体的业务逻辑

11.调用拦截器后置(数组倒序执行)

12.将所有过滤器的后置代码执行完毕(方法栈,先进后出)

13.将结果返回给请求者

注意,过滤器和拦截器实现先进后出的实现方式是不同的,过滤器基于函数回调,方法栈结构天生支持先进后出;拦截器则是直接使用循环倒序遍历

总结

同:

  • 过滤器和拦截器都遵循面向切面编程的思想(AOP),实现了在请求到达目标处理器(Servlet/Controller)之前或者之后插入自定义的处理逻辑

异:

  • 使用范围不同

    过滤器实现的是javax.servlet.Filter该接口在Servlet规范中定义,依赖WEB容器

    拦截器是一个Spring组件,由Spring管理,并不依赖Tomcat容器,可以单独使用(Application,Swing)

  • 使用的场景不同

    拦截器更加接近业务系统,所以拦截器更适用于处理统一的业务逻辑,比如权限判断等

    过滤器通常用来实现通用功能,比如xss过滤,敏感词,处理跨域等等

  • 触发的时机不同

    过滤器的触发时机早于拦截器

  • 底层实现细节不同

    过滤器实现先进后出基于方法栈的数据结构

    拦截器实现先进后出基于循环倒序遍历文章来源地址https://www.toymoban.com/news/detail-838494.html

到了这里,关于过滤器和拦截器的辨析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 过滤器,监听器与拦截器的区别

    ​ 过滤器和监听器不是Spring MVC中的组件,而是Servlet的组件,由Servlet容器来管理。拦截器是Spring MVC中的组件,由Spring容器来管理 ​ Servlet过滤器与Spring MVC 拦截器在Web应用中所处的层次如下图所示: 过滤器是Servlet的高级特性之一,是实现Filter接口的Java类。其基本功能就是对

    2024年02月14日
    浏览(53)
  • 登录页面jwt密钥,过滤器,拦截器,异常处理

    需求: 用户未登录时,访问其他也没面,操作添加、删除等操作时,强行跳转至登录页面。 实现方法: 1.使用Cookie,登录后后端添加一个cookie,每次页面判断是否有cookie, 2。使用session,原理同上,只不过session是存储在服务器里的,cookie是在浏览器里。 3。使用jwt令牌,登

    2023年04月25日
    浏览(53)
  • Springboot中使用拦截器、过滤器、监听器

    Javaweb三大组件:servlet、Filter(过滤器)、 Listener(监听器) SpringBoot特有组件:Interceptor(拦截器) 过滤器、拦截器、监听器、AOP(后续文章介绍)、全局异常处理器(后续文章介绍)是搭建系统框架时,经常用到的部分,全局异常处理器的作用很明显,就是处理接口执行

    2024年02月03日
    浏览(43)
  • Spring Boot拦截器与过滤器的区别

    在使用Spring Boot开发Web应用程序时,您可能需要在处理请求之前或之后执行某些操作。这些操作可以包括身份验证、日志记录、性能监测等。在这种情况下,您可以使用两种不同的机制:拦截器和过滤器。本文将介绍这两种机制及其区别,并提供一些示例代码来演示如何在S

    2024年02月08日
    浏览(56)
  • spring boot 过滤器&拦截器与aop

    在使用 Spring 框架时,可以通过在 web.xml 配置文件中注册过滤器,使其在请求进入 Spring 前就能够进行预处理。这样可以在请求进入 Spring MVC 的 DispatcherServlet 之前,对请求进行拦截、修改或者过滤。 过滤器在 Spring 中的应用场景包括但不限于: 字符编码过滤:通过过滤器,在

    2024年02月01日
    浏览(49)
  • SpringBoot2.0(过滤器,监听器,拦截器)

    使用Servlet3.0的注解进行配置 启动类里面增加 @ServletComponentScan ,进行扫描 新建一个Filter类,implements Filter ,并实现对应接口 @WebFilter 标记一个类为Filter,被spring进行扫描 urlPatterns:拦截规则,支持正则 控制chain.doFilter的方法的调用,来实现是否通过放行, 不放行的话,web应用

    2024年02月07日
    浏览(42)
  • springbboot拦截器,过滤器,监听器及执行流程

    过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前 请求按照上图进入conteoller后执行完再返回 过滤器是Servlet规范中定义的一种组件,可以用于在请求进入Web应用程序之前或响应离开Web应用程序之前对请

    2024年02月13日
    浏览(43)
  • 过滤器(Filter)和拦截器(Interceptor)有什么不同?

    过滤器(Filter)和拦截器(Interceptor)是用于处理请求和响应的中间件组件,但它们在实现方式和应用场景上有一些不同。 过滤器 是Servlet规范中定义的一种组件,通常以Java类的形式实现。过滤器通过在 web.xml 配置文件中声明来注册,并在Web应用程序的请求和响应链中拦截请

    2024年02月07日
    浏览(38)
  • SpringBoot 统计API接口用时该使用过滤器还是拦截器?

    统计请求的处理时间(用时)既可以使用 Servlet 过滤器(Filter) ,也可以使用 Spring 拦截器(Interceptor) 。两者都可以在请求处理前后插入自定义逻辑,从而实现对请求响应时间的统计。 如果你需要在更底层、与框架无关的地方记录所有请求(包括静态资源请求)的处理时间

    2024年01月18日
    浏览(47)
  • 75.SpringMVC的拦截器和过滤器有什么区别?执行顺序?

    拦截器不依赖与servlet容器,过滤器依赖与servlet容器。 拦截器只能对action请求(DispatcherServlet 映射的请求)起作用,而过滤器则可以对几乎所有的请求起作用。 拦截器可以访问容器中的Bean(DI),而过滤器不能访问(基于spring注册的过滤器也可以访问容器中的bean)。 过滤器 和 拦

    2024年02月22日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包