• 【BUG】ServerHttpResponseDecorator失效


    1.BUG描述

    1. BUG描述

    在Spring Cloud Gateway使用编码的方式实现一个全局拦截器,在全局拦截器中想要打印响应日志。

    于是自己装饰了一个具有打印日志功能的ServerHttpResponseDecorator,但是在转发后的服务返回响应的时候,ServerHttpResponseDecorator的writeWith却并没有执行

    @Component
    @Slf4j
    public class CustomGlobaFilter implements GlobalFilter, Ordered {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            //响应日志
            return handleResponse(exchange, chain);
        }
    
        public Mono<Void> handleResponse(ServerWebExchange exchange, GatewayFilterChain chain) {
            try {
                ServerHttpResponse originalResponse = exchange.getResponse();
                // 缓存数据的工厂
                DataBufferFactory bufferFactory = originalResponse.bufferFactory();
                // 拿到响应码
                HttpStatus statusCode = originalResponse.getStatusCode();
                if (statusCode == HttpStatus.OK) {
                    // 装饰,增强能力
                    ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
                        // 等调用完转发的接口后才会执行
                        @Override
                        public Mono<Void>  writeWith(Publisher<? extends DataBuffer> body) {
                            log.info("body instanceof Flux: {}", (body instanceof Flux));
                            if (body instanceof Flux) {
                                Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                                // 往返回值里写数据
                                // 拼接字符串
                                return super.writeWith(
                                        fluxBody.map(dataBuffer -> {
                                            byte[] content = new byte[dataBuffer.readableByteCount()];
                                            dataBuffer.read(content);
                                            //释放掉内存
                                            DataBufferUtils.release(dataBuffer);
                                            // 构建日志
                                            StringBuilder sb2 = new StringBuilder(200);
                                            List<Object> rspArgs = new ArrayList<>();
                                            rspArgs.add(originalResponse.getStatusCode());
                                            //data
                                            String data = new String(content, StandardCharsets.UTF_8); 
                                            sb2.append(data);
                                            // 打印日志
                                            log.info("响应结果:" + data);
                                            return bufferFactory.wrap(content);
                                        }));
                            } else {
                                // 8. 调用失败,返回一个规范的错误码
                                log.error("<--- {} 响应code异常", getStatusCode());
                            }
                            return super.writeWith(body);
                        }
                    };
                    // 设置 response 对象为装饰过的
                    return chain.filter(exchange.mutate().response(decoratedResponse).build());
                }
                // 降级处理返回数据
                return chain.filter(exchange); 
            } catch (Exception e) {
                log.error("网关处理响应异常" + e);
                return chain.filter(exchange);
            }
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    2.BUG解决

    将这种写法

    @Slf4j
    @Component
    @Order(-2) <--------------将这个
    public class CustomGlobalFilter implements GlobalFilter , Ordered {
    ........省略
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    改为这种方式

        @Override
        public int getOrder() {
            return -2;
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.BUG分析

    查阅官网文档

    1. 官网文档案例采用的是实现接口的方式
        @Override
        public int getOrder() {
            return -2;
        }
    
    • 1
    • 2
    • 3
    • 4
    1. 查阅资料之后没有找到详细的解答,还是遵循官方的规范吧,时间有限,不纠结,意义不大。
  • 相关阅读:
    溢出、截断、类型提升:从易错代码入手分析整型数据存储与类型转换
    HTML5+CSS3+Vue小实例:输入框打字放大特效
    Hudi(三)集成Flink
    阿里巴巴Java面试题、笔试题(含答案)
    mavicat打开本地连接显示2002-Can‘t connnect to server on ‘localhost‘(10061)
    当你在Linux系统中编译安装MySQL数据库卡住了怎么办?
    Linux Ubuntu命令行快速配置C++开发环境
    从TF-IDF 到BM25, BM25+,一文彻底理解文本相关度
    nignx配置文件种的跳转
    流媒体文件以及网络应用直播技术
  • 原文地址:https://blog.csdn.net/imbzz/article/details/137845317