V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bai821547889
V2EX  ›  Java

请问 Spring cloud gateway 如何在 filter 中解析请求中的文件和字符串变量呢?

  •  
  •   bai821547889 · 2023-09-09 16:12:33 +08:00 · 925 次点击
    这是一个创建于 434 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位前辈好,因为我刚接触 Spring cloud gateway ,不太懂这个框架,想请教个问题。

    我这个功能逻辑是这样的:在一个自定义的局部过滤器,通过getMultipartData()来解析请求中的文件和字符串变量后做一些业务逻辑,然后不继续走别的过滤器,直接返回。

    但是我的这份代码问题在于:

    • 如果拦截掉这个请求,即return exchange.getResponse().setComplete()并不会触发getMultipartData()这个流,得不到数据;
    • 但如果放行这个请求,即return chain.filter(exchange),却可以触发这个流,获得数据。

    请问这个现象是因为什么引起呢,或者啥关键词可以提示一下?我从凌晨三四点就开始考虑这个问题了,实在无能为力。 谢谢大家。

    @Slf4j
    @Component
    public class FileFilterGatewayFilterFactory extends
            AbstractGatewayFilterFactory<FileFilterGatewayFilterFactory.ParamsConfig>{
    
    
        public FileFilterGatewayFilterFactory() {
            super(FileFilterGatewayFilterFactory.ParamsConfig.class);
        }
    
        @Override
        public GatewayFilter apply(FileFilterGatewayFilterFactory.ParamsConfig config) {
            return new OrderedGatewayFilter(((exchange, chain) -> {
                parseBody(exchange).subscribe();
                
                
                // 如果放行,可以触发 parseBody 里面的方法
                return chain.filter(exchange);
                
                
                // 如果不放行,parseBody 里面的方法根本不执行
                return exchange.getResponse().setComplete();
            }),10);
    
        }
    
        public Mono<Object> parseBody(@NotNull ServerWebExchange exchange) {
            return exchange.getMultipartData().map(multipartData -> {
                Map<String, Part> partMap = multipartData.toSingleValueMap();
                Part file = partMap.get("file");
                FormFieldPart bizName = (FormFieldPart) partMap.get("name");
                return Result.buildSuccessResult("成功", null);
            });
        }
    
    2 条回复    2023-09-09 18:20:04 +08:00
    mmdsun
        1
    mmdsun  
       2023-09-09 17:39:29 +08:00
    没怎么用过 spring gateway ,看了下文档,继承 ModifyRequestBodyGatewayFilterFactory 等官方提供好的类,比较好实现。不执行返回执行,可以抛个异常,然后用写个异常处理器返回错误信息。

    再说代码问题,一般来说,subscribe 方法是异步的,会在另一个线程中执行反应式流,不会等待它的结果。
    parseBody 不执行,可能是前线程在 subscribe()方法执行之前就结束了。

    代码应该使用操作符来连接你的流,比如:
    return parseBody(exchange).flatMap(result -> exchange.getResponse().setComplete());
    bai821547889
        2
    bai821547889  
    OP
       2023-09-09 18:20:04 +08:00
    @mmdsun 😘谢谢大佬,听到您的建议,豁然开朗,代码按照您说的,问题已经解决了,真的非常感谢。👍👍👍
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1105 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:29 · PVG 07:29 · LAX 15:29 · JFK 18:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.