请求处理

Ho1d_F0rward / 2024-08-18 / 原文

基础概念

  • 过滤器(Filter):当有一堆请求,只希望符合预期的请求进来。
  • 拦截器(Interceptor):想要干涉预期的请求。
  • 监听器(Listener):想要监听这些请求具体做了什么。

过滤器

  • 过滤敏感词汇(防止sql注入)
  • 设置字符编码
  • URL级别的权限访问控制
  • 压缩响应信息

最常见使用的接口是OncePerRequestFilter和Filter接口

作用范围

  • Filter 是一个更通用的接口,可以拦截任何请求,包括静态资源的请求。
  • OncePerRequestFilter 是 Filter 接口的一个具体实现,它只拦截动态请求(Servlet、JSP 等),不会拦截静态资源的请求。

执行次数

  • Filter 可以被多次执行,每次请求都会经过 Filter 链。
  • OncePerRequestFilter 保证了一次请求只会执行一次过滤操作,即使被多个 OncePerRequestFilter 实现类匹配。

常见用途

  • Filter 通常用于实现一些通用的功能,如身份验证、日志记录、字符编码设置等。
  • OncePerRequestFilter 通常用于实现一些需要在请求处理的整个生命周期中执行的功能,如安全检查、性能监控等。

拦截器

一个拦截器必须实现 HandlerInterceptor 接口,preHandle 方法是 Controller 方法调用前执行,postHandle 是 Controller 方法正常返回后执行,afterCompletion 方法无论 Controller 方法是否抛异常都会执行。

@Slf4j
public class LoggerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("preHandle{}...",request.getRequestURI());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

监听器

Spring Boot监听器主要分为以下几类:

  • ApplicationListener:用于监听Spring应用上下文事件。
  • ServletListener:用于监听Servlet生命周期事件。
  • ContextRefreshedListener:用于监听Spring上下文刷新事件。

除了Spring提供的事件外,开发者还可以自定义事件,以满足特定需求。这里我们主要说明一下自定义事件的监听。

自定义事件类

import org.springframework.context.ApplicationEvent;
public class UserRegisteredEvent extends ApplicationEvent {
    private String username;
    public UserRegisteredEvent(Object source, String username) {
        super(source);
        this.username = username;
    }
    public String getUsername() {
        return username;
    }
}

发布事件

import org.springframework.context.ApplicationEventPublisher;
import  org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;


@Component
public class UserService implements ApplicationEventPublisherAware {
    private ApplicationEventPublisher eventPublisher;
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }
    public void registerUser(String username) {
        // Logic to register the user
        System.out.println("User registered: " + username);
        // Publish the UserRegisteredEvent
        UserRegisteredEvent event = new UserRegisteredEvent(this, username);
        eventPublisher.publishEvent(event);
    }
}

监听事件类

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class UserRegisteredListener implements ApplicationListener<UserRegisteredEvent> {
    @Override
    public void onApplicationEvent(UserRegisteredEvent event) {
        System.out.println("User registered event received for user: " + event.getUsername());
    }
}

参考链接

https://javabetter.cn/springboot/Filter-Interceptor-Listener.html#前言
https://www.yanfukun.com/read/springbootdetail/listener?wd=springboot