Servlet过滤器拦截器

1、什么是Servlet?

参考:https://blog.csdn.net/wozaibohaibian/article/details/124778494

​ servlet就是一个组件,需要符合servlet规范,并且需要部署到servlet容器里面才能运行

注:容器:符合相应的规范,提供组件运行环境的程序。比如Tomcat就是比较有名的servlet容器。jetty jboss weblogic都是servlet容器。这些servlet把网络相关的问题已经全部处理好,我们写servlet只需要关注业务逻辑即可。

2、过滤器与拦截器的区别

参考:https://zhuanlan.zhihu.com/p/340673453

过滤器

​ 过滤器(Filter)属于Servlet的范畴可以认为是Servlet的一种“加强版”,通过实现javax.servlet.Filter接口来实现功能。主要用于对用户请求进行预处理,是个典型的处理链。通常使用场景:==检查用户授权、记录日志信息、解码、过滤字符编码==等。

  1. 基本工作原理:

​ 配置完过滤器及需要拦截的请求,当请求到来时,通过过滤器提供的方法可以对请求或响应(Request、Response)统一处理。比如,可判断用户是否登录,是否拥有请求的访问权限等。在Web应用启动时,过滤器仅会被初始化一次,便可处理后续请求,只有Web应用停止或重新部署时才能销毁。

使用Filter完整的流程是:Filter对用户请求进行“预处理”,接着将请求交给Servlet进处理并生成响应,最后Filter再对服务器响应进行“后处理”

上述流程具体到类的处理就是:

  1. Filter在ServletRequest到达Servlet之前,拦截客户的ServletRequest;
  2. 根据需要检查ServletRequest,也可修改ServletRequest头和数据;
  3. 在ServletResponse到达客户端之前,拦截ServletResponse;
  4. 根据需要检查HttpServletResponse,也可修改HttpServletResponse头和数据。

创建Filter必须实现javax.servlet.Filter接口,该接口定义了3个方法

  • void init(FilterConfig filterConfig):容器启动初始化Filter时会被调用,整个生命周期只会被调用一次。可用于完成Filter的初始化。
  • void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 实现过滤功能,就是通过该方法对每个请求增加额外的处理。通过其参数FilterChain调用下一个过滤器。
  • void destroy():用于Filter销毁前,完成某些资源的回收。

其中,doFilter方法便是实现对用户请求进行预处理(ServletRequest request)和对服务器响应进行后处理(ServletResponse response)的方法。预处理和后处理的分界线为是否调用了chain.doFilter()。在执行该方法之前,是对用户请求进行预处理,在执行该方法之后,是对服务器响应进行后处理。

代码展示:

public class LogFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter 初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter 预处理");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("Filter 后处理");
    }

    @Override
    public void destroy() {
        System.out.println("容器销毁");
    }
}

关于Filter的使用在普通的Web项目中可在web.xml中配置:

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>com.secbro2.learn.filter.LogFilter</filter-class>
    <async-supported>true</async-supported>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

如果是SpringBoot项目,首先使用@Component将LogFilter实例化,然后通过如下配置文件,进行具体的配置:

@Configuration
public class FilterConfig {

    @Resource
    private LogFilter logFilter;

    @Bean
    public FilterRegistrationBean<Filter> registerAuthFilter() {
        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
        registration.setFilter(logFilter);
        registration.addUrlPatterns("/*");
        registration.setName("authFilter");
        // 值越小,Filter越靠前
        registration.setOrder(1);
        return registration;
    }
}

定义一个Contoller,然后依次执行启动项目、访问Controller、关闭项目,打印的日志信息依次为:

Filter 初始化
---以上为启动项目时打印---
Filter 预处理
Controller中处理业务逻辑
Filter 后处理
---以上为访问Controller时打印---
容器销毁
---以上为关闭服务时打印---

拦截器

​ 拦截器,在AOP(Aspect-Oriented Programming)中用于某个方法或字段被访问之前进行拦截,然后在其之前或之后加入某些操作。拦截器作为动态拦截Action调用的对象,它提供了一种机制使开发者可以在Action执行前后定义可执行的代码,也可以在Action执行前阻止其执行。拦截器将Action共用的行为独立出来,在Action执行前后执行。常见的应用场景比如权限管理、日志服务等

如何实现

在Spring MVC当中要使用拦截器需要实现org.springframework.web.servlet.HandlerInterceptor接口,该接口定义了如下3个方法:

  1. preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法,会在请求处理之前被调用。SpringMVC中的Interceptor是链式调用的,可以存在多个Interceptor。Interceptor的调用会依据声明顺序依次执行,最先执行的都是preHandle方法,可在该方法中进行一些前置(预)处理,也可进行判断来决定是否要继续执行。当返回为false 时,表示请求结束,后续的Interceptor和Controller都不会再执行;当返回值为true时,会继续调用下一个Interceptor的preHandle方法,执行完最后一个Interceptor后会调用当前请求的Controller方法。
  2. postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,会在Controller方法调用之后,DispatcherServlet进行渲染视图之前被调用,所以可以对Controller处理之后的ModelAndView对象进行操作。postHandle方法被调用的方向跟preHandle是相反的,先声明的Interceptor的postHandle方法反而会后执行。
  3. afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,会在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行。这个方法的主要是用于进行资源清理。

示例:

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("Interceptor preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("Interceptor postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("Interceptor afterCompletion");
    }
}

对应LoginInterceptor需添加到Spring MVC当中:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Resource
    private LoginInterceptor loginInterceptor;

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

这里拦截所有的请求,执行对应的Controller之后,会看到打印如下信息:

当一个请求过来之后,会先后执行preHandle方法、Controller中的业务、postHandle方法和afterCompletion方法。

Interceptor preHandle
Controller中处理业务逻辑
Interceptor postHandle
Interceptor afterCompletion
过滤器拦截器
原理不同基于回调函数Java的反射机制实现
作用范围不同实现javax.servlet.Filter接口,过滤器在只在Servlet前后起作用定义在org.springframework.web.servlet包下,由Spring容器管理【又有更加丰富的生缪那个周期处理方法,细粒度,且能够使用Spring中的Bean资源,方便业务访问】,拦截器能够深入到方法前后、异常抛出前后,对Action请求其作用,可以访问Action上下文、值栈里的对象等,具有更大的弹性。因此,在Spring框架的过程中,要优先使用拦截器。
触发时机不同对请求在进入后Servlet之前或之后进行处理对请求在handler【Controller】前后进行处理。
使用资源不同过滤器不能拦截器可以使用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过IOC注入到拦截器即可
使用范围与规范不同过滤器是Servlet规范中定义的,只能用于Web程序中,依赖于Servlet容器拦截器是Spring的组件,可用于Web程序、Application、Swing等程序,不依赖Servlet容器
img

1、使用范围与规范不同:Filter是Servlet规范中定义的,只能用于Web程序中,依赖于Servlet容器。拦截器是Spring的组件,可用于Web程序、Application、Swing等程序,不依赖Servlet容器。

2、使用资源不同:拦截器可以使用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过IOC注入到拦截器即可;而Filter则不能。

3、作用范围不同:Filter在只在Servlet前后起作用。而拦截器能够深入到方法前后、异常抛出前后,对Action请求其作用,可以访问Action上下文、值栈里的对象等,具有更大的弹性。因此,在Spring框架的过程中,要优先使用拦截器。而滤器则可以对几乎所有的请求起作用。

4、实现机制不同:拦截器是基于java的反射机制的,而过滤器是基于函数回调。

img

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Servlet过滤器拦截器Java Web开发中常用的组件,用于在请求处理流程中进行预处理或后处理操作。它们之间的主要区别如下: 1. 运行位置不同: - 过滤器:在Servlet容器中的Servlet调用前后执行,即位于Servlet之前拦截请求或之后拦截响应。 - 拦截器:在DispatcherServlet处理请求前后执行,即位于Controller之前拦截请求或之后拦截响应。 2. 功能不同: - 过滤器:通过在请求处理前后进行过滤,可以修改请求参数、检查用户权限、记录日志等。 - 拦截器:更加专注于请求的处理流程,可以对请求进行控制、修改ModelAndView对象、异常处理等。 3. 使用方式不同: - 过滤器:在web.xml文件中配置过滤器名称及执行顺序,过滤器可以过滤所有的Servlet请求或静态资源请求。 - 拦截器:通过在Spring配置文件中使用<interceptors>标签来配置拦截器拦截器只能拦截Spring MVC中的请求。 4. 生命周期不同: - 过滤器:在Servlet容器启动时创建,随Servlet容器的启停而启停。 - 拦截器:由Spring容器管理,随Spring容器的启停而启停。 综上所述,过滤器既可以拦截Servlet请求也可以拦截静态资源请求,功能更灵活多样;而拦截器专注于对请求处理的控制和修改,灵活性相对较强。在实际应用中,选择使用过滤器还是拦截器,可以根据具体的需求和场景进行合理选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小凯77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值