SpringMVC与WebFlux的拦截器及过滤器

拦截器

java 复制代码
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * MVC 拦截器 for 汉服换脸
 */
@Component
@Slf4j
public class ApiSignInterceptorForHanfu implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    ...

以上是一个MVC拦截器的声明,org.springframework.web.servlet.config.annotation.WebMvcConfigurer的路径拦截配置(如下)也没有问题。奇怪的是,用上面的拦截器拦截非流式方法时,这拦截器的com.zju.design.config.ApiSignInterceptorForHanfu#preHandle方法只会运行一次,如果用它拦截流式方法,则preHandle方法会运行两次,其中第二次是Controller方法运行结束后。注:此项目同时有SpringMVC和spring webflux依赖。

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Resource
    private ApiSignInterceptorForHanfu apiSignInterceptorForHanfu;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {   		
        registry.addInterceptor(apiSignInterceptorForHanfu).addPathPatterns("/hanfu/generating/**");
    }
  • 豆包的解释:

  • Q: 有没有与MVC 拦截器对应的webflux拦截器,我用它来拦截流式方法,使拦截器的关键代码只运行一次?
    A:据说在spring webflux环境中,可以使用org.springframework.web.reactive.function.server.HandlerFilterFunction + org.springframework.web.reactive.config.WebFluxConfigurer

过滤器

若项目存在 spring-boot-starter-web 依赖(MVC 核心),且没有 spring-boot-starter-webflux依赖,则项目是 MVC 环境,WebFlux过滤器(WebFilter)必然不生效,只会生效 MVC的过滤器;

若两者都存在,Spring 会默认使用 MVC 容器(Tomcat),WebFlux 过滤器也不会生效。

我的SpringMVC过滤器:

java 复制代码
/**
 * MVC 过滤器
 */
@Component
@Slf4j
public class HttpParameterFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        filterChain.doFilter(request, response);
    }
    。。。

豆包的解释: https://www.doubao.com/thread/w70fcca28c363d4d2

下面是一个WebFlux 过滤器实例:

java 复制代码
package com.zju.design.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

/**
 * WebFlux 过滤器(WebFilter)for 汉服换脸
 */
@Component
@Slf4j
public class ApiSignWebFilterForHanfu implements WebFilter {

    public ApiSignWebFilterForHanfu() {
        log.info("ApiSignWebFilterForHanfu init");
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        log.info("filter");
        // 1. 放行 OPTIONS 预检请求(核心修改)
        if ("OPTIONS".equalsIgnoreCase(exchange.getRequest().getMethod().name())) {
            return chain.filter(exchange);
        }

        String path = exchange.getRequest().getPath().value();
        if (!path.startsWith("/hanfu/generating/stream/swapFace")) {
            log.info("filter no path:{}", path);
            return chain.filter(exchange);
        }

        // 检查标志位,如果已经执行过,则直接放行. 为了回避重复执行
        if (Boolean.TRUE.equals(exchange.getAttribute("checkSignExecuted"))) {
            log.info("checkSignExecuted, skip");
            return chain.filter(exchange);
        }
        // 设置标志位为 true
        exchange.getAttributes().put("checkSignExecuted", Boolean.TRUE);
        return chain.filter(exchange);
    }

}
相关推荐
ttod_qzstudio4 天前
深入理解 TypeScript 数组的 find 与 filter 方法:精准查找的艺术
javascript·typescript·filter·find
我叫张小白。20 天前
Spring Boot拦截器详解:实现统一的JWT认证
java·spring boot·web·jwt·拦截器·interceptor
洛克大航海1 个月前
9-SpringCloud-服务网关 Gateway-高级特性之 Filter-2
java·spring cloud·gateway·filter
洛克大航海2 个月前
9-SpringCloud-服务网关 Gateway-高级特性之 Filter-1
spring·spring cloud·gateway·filter
清静诗意2 个月前
【Django FilterSet 深入解析】类属性过滤器与 Meta.fields 的关系详解(附源码分析)
django·filter
元亓亓亓3 个月前
JavaWeb--day11--登录认证
springboot·web·interceptor·cookie·filter·session
茶本无香3 个月前
RequestContextFilter介绍
java·spring·filter·requestcontext
岚天start4 个月前
iptables -L 显示无目标链规则,但是iptables-save显示仍存在链规则原因分析
linux·服务器·网络·iptables·nat·filter·mangle
Mr_Chenph4 个月前
Qdrant Filtering:must / should / must_not 全解析(含 Python 实操)
python·filter·qdrant