SpringBoot 统计API接口用时该使用过滤器还是拦截器?

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

统计请求的处理时间(用时)既可以使用 Servlet 过滤器(Filter),也可以使用 Spring 拦截器(Interceptor)。两者都可以在请求处理前后插入自定义逻辑,从而实现对请求响应时间的统计。

使用建议

如果你需要在更底层、与框架无关的地方记录所有请求(包括静态资源请求)的处理时间,那么 Servlet 过滤器是一个更好的选择。

如果你正在使用 Spring MVC 并且关注的是 Controller 层的处理时间,或者需要访问到 Spring 上下文中的服务,那么 Spring 拦截器可能更为合适。

代码样例

Servlet 过滤器(Filter)

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.Instant;

// @Component 注册时会new 这里无需指定 registration.setFilter(new LogFilter());
@Slf4j
public class LogFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.err.println("***LogFilter.doFilter.start***");
        HttpServletRequest httpReq = (HttpServletRequest) request;
        long startTime = Instant.now().toEpochMilli();

        // 记录请求开始时间及请求信息
        log.warn("LogFilter.doFilter: Start processing request at {} - {}", Instant.now(), httpReq.getRequestURI());

        try {
            // 将请求传递给下一个过滤器或目标资源
            chain.doFilter(request, response);
        } finally {
            // 记录请求结束时间及响应状态码
            long endTime = Instant.now().toEpochMilli();
            int statusCode = ((HttpServletResponse) response).getStatus();
            log.warn("LogFilter.doFilter: Finished processing request at {} - {} in {} ms. Status code: {}", Instant.now(), httpReq.getRequestURI(), (endTime - startTime), statusCode);
        }
        System.err.println("***LogFilter.doFilter.end***");
    }
}

注册过滤器(Filter)

@Configuration
public class AppConfig {
    @Bean
    public FilterRegistrationBean<LogFilter> tokenFilterRegistration() {
        FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new LogFilter());
        // 可以设置过滤器名称
        registration.setName("logFilter");
        // 设置拦截规则
        registration.addUrlPatterns("/*"); // 拦截所有请求
        // 设置过滤器执行顺序,默认为0,数值越小优先级越高
        registration.setOrder(1);
        return registration;
    }
}

Spring 拦截器(Interceptor)

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.time.Instant;

@Component
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.err.println("***LogInterceptor.preHandle***");
        long startTime = Instant.now().toEpochMilli();
        request.setAttribute("startTime", startTime);
        log.warn("LogInterceptor.postHandle: Start processing request at {} - {}", Instant.now(), request.getRequestURI());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.err.println("***LogInterceptor.preHandle***");
        // 获取请求开始时间
        Long startTime = (Long) request.getAttribute("startTime");
        if (startTime != null) {
            long executionTime = Instant.now().toEpochMilli() - startTime;
            int statusCode = response.getStatus();
            log.warn("LogInterceptor.postHandle: Finished processing request at {} - {} in {} ms. Status code: {}", Instant.now(), request.getRequestURI(), executionTime, statusCode);
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.err.println("***LogInterceptor.afterCompletion***");
        // 在此可以添加额外的后处理逻辑,但本例中我们不需要
    }
}

注册拦截器(Interceptor)

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ResponsePostInterceptor responsePostInterceptor;
    @Autowired
    private LogInterceptor logInterceptor;

    /**
     * 为拦截器注册表添加拦截器
     *
     * @param registry 拦截器注册表
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 在Spring MVC配置中注册一个名为responsePostInterceptor的拦截器,使其能够对匹配路径“/**”(即对应用程序中的所有路径)的请求进行拦截
        registry.addInterceptor(responsePostInterceptor).addPathPatterns("/**");
        registry.addInterceptor(logInterceptor).addPathPatterns("/**");
    }
}

[Ref] 在Spring Boot中注册过滤器几种方式

测试验证

SpringBoot 统计API接口用时该使用过滤器还是拦截器?,框架,SpringMVC,SpringBoot,spring boot,后端,java

SpringBoot 统计API接口用时该使用过滤器还是拦截器?,框架,SpringMVC,SpringBoot,spring boot,后端,java文章来源地址https://www.toymoban.com/news/detail-801425.html

# 过滤器开始计时
***LogFilter.doFilter.start***
[2024-01-17 08:17:55] [WARN ] [http-nio-8080-exec-2] [LogFilter.java:22][LogFilter.doFilter: Start processing request at 2024-01-17T00:17:55.662652400Z - /students]
***RequestHeaderCheckFilter.doFilter.start***

# 拦截器组的 preHandle
***ResponsePostInterceptor.preHandle***
# log用时拦截器开始计时
***LogInterceptor.preHandle***
[2024-01-17 08:17:55] [WARN ] [http-nio-8080-exec-2] [LogInterceptor.java:20][LogInterceptor.postHandle: Start processing request at 2024-01-17T00:17:55.852229500Z - /students]

# Controller层
***StudentController.edit***
[2024-01-17 08:17:56] [INFO ] [http-nio-8080-exec-2] [HikariDataSource.java:110][practisedb - Starting...]
[2024-01-17 08:17:56] [INFO ] [http-nio-8080-exec-2] [HikariPool.java:565][practisedb - Added connection com.mysql.cj.jdbc.ConnectionImpl@34a6ebfc]
[2024-01-17 08:17:56] [INFO ] [http-nio-8080-exec-2] [HikariDataSource.java:123][practisedb - Start completed.]

# @ControllerAdvice对Response增强,比如修改状态码,补充header值
***ResponsePostAdvice.supports***
***ResponsePostAdvice.beforeBodyWrite***

# 拦截器组的 postHandle
***LogInterceptor.postHandle***
# log用时拦截器结束计时
[2024-01-17 08:17:56] [WARN ] [http-nio-8080-exec-2] [LogInterceptor.java:32][LogInterceptor.postHandle: Finished processing request at 2024-01-17T00:17:56.636557900Z - /students in 784 ms. Status code: 200]
***ResponsePostInterceptor.postHandle***

# 拦截器组的 afterCompletion
***LogInterceptor.afterCompletion***
***ResponsePostInterceptor.afterCompletion***

# 过滤器结束计时
***RequestHeaderCheckFilter.doFilter.end***
[2024-01-17 08:17:56] [WARN ] [http-nio-8080-exec-2] [LogFilter.java:31][LogFilter.doFilter: Finished processing request at 2024-01-17T00:17:56.920165800Z - /students in 1258 ms. Status code: 200]
***LogFilter.doFilter.end***

到了这里,关于SpringBoot 统计API接口用时该使用过滤器还是拦截器?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Springboot 在 redis 中使用 BloomFilter 布隆过滤器机制

    在 pom.xml 文件中,引入Spring Boot和Redis相关依赖 创建一个布隆过滤器配置类 BloomFilterConfig : 创建一个BloomFilterController。使用布隆过滤器判断数据是否存在,从而避免缓存穿透: 向里面添加元素  获取元素

    2024年02月13日
    浏览(28)
  • Springboot 在 redis 中使用 Guava 布隆过滤器机制

    在 pom.xml 文件中,引入Spring Boot和Redis相关依赖 创建一个布隆过滤器配置类 BloomFilterConfig : 创建一个BloomFilterController。使用布隆过滤器判断数据是否存在,从而避免缓存穿透: 向里面添加元素  获取元素

    2024年02月12日
    浏览(27)
  • springboot中过滤器@WebFilter的使用以及简单介绍限流算法

    过滤器(Filter)实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理,通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理,大致流程如下图 一般情况下,我们针对一些敏感的参数,例如密码、身份证号等,给它加密,防止报文明文

    2024年02月03日
    浏览(28)
  • 【Spring】Springboot过滤器Filter和拦截器Inteceptor详解及使用场景

    Springboot过滤器Filter和拦截器Inteceptor详解及使用场景

    2024年02月13日
    浏览(35)
  • SpringBoot在使用SpringSecurity时,配置跨域过滤器CorsFilter不生效分析解决

    此文中代码只粘贴部分代码,完整版请自行查看 请求一般为重启debug服务再次请求 一般配置方法(适用于没有SpringSecurity配置时) SpringSecurity配置时配置方法 首先说明Spring中过滤器加载使用的是FilterRegistrationBean配置过滤器,FilterRegistrationBean实现了Ordered接口,order排序值默认值为

    2024年01月20日
    浏览(28)
  • SpringBoot 统计更多Api接口日志信息

    Further Reading : SpringBoot 统计API接口用时该使用过滤器还是拦截器? 日志打印放afterCompletion是为了兼容异常场景也可以记录日志 配置文件可以配置是否开启统计

    2024年01月23日
    浏览(45)
  • spring boot过滤器实现项目内接口过滤

    由于业务需求,存在两套项目,一套是路由中心,一套是业务系统. 现在存在问题是,路由中心集成了微信公众号与小程序模块功能,业务系统部署了多套服务. 现在需要通过调用路由中心将接口重新路由到指定的业务系统中 将小程序,公众号用户信息与业务系统做绑定 将路由中心的

    2023年04月20日
    浏览(34)
  • 程序化交易接口策略过滤器–九宫格

    不同的程序化交易接口策略适用于不同的市场情况,有些交易策略使用于均值回归,有些则试用于方向明显的时候,有些试用于方向不明显的时候,因此,我们需要根据不同的市场情况,综合考虑方向和波动率,市场成交量来选择合适的交易策略。 本文介绍了一种选择程序化

    2023年04月09日
    浏览(32)
  • Springboot 过滤器

    拦截器和过滤器的区别: 过滤器(Filter) :可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。 拦截器(Interceptor):可以拿到你请求的控制器和方法,却拿不到请求方法的参数。 切片(Aspect): 可以拿到方法的参数,但是却拿不到http请求和

    2023年04月15日
    浏览(29)
  • springboot 过滤器链 来自 chatgpt

    当需要在Spring Boot中配置多个过滤器时,可以按照以下步骤进行操作: 创建多个自定义过滤器类:首先,你需要创建多个实现 javax.servlet.Filter 接口的自定义过滤器类,每个过滤器类都需要实现 doFilter 方法来定义过滤器的逻辑处理。 配置过滤器链:在Spring Boot应用程序的配置

    2024年02月12日
    浏览(30)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包