【Spring Cloud GateWay】ServerHttpResponseDecorator不生效

news2024/11/16 6:49:55

文章目录

  • 1. BUG描述
  • 2. BUG解决
  • 3. BUG分析

1. BUG描述

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

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

@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;
    }
}

2. BUG解决

getOrder方法的返回值设置为-2

@Override
public int getOrder() {
    return -2;
}

修改成之后,writeWith方法在服务返回响应的时候就能被调用了。


3. BUG分析

在SpringCloudGateway中,有很多默认的全局过滤器。

img

它们对应的order值如下图所示

img

因为我这里的CustomGlobaFilter实现了Ordered,所以它的order就是它自己设定的值。

否则,它就没有order。

查看了大量信息,最后得知,自定义的GlobaFilter的order必须小于-1,否则标准 NettyWriteResponseFilter 将在过滤器有机会被调用之前发送响应。


参考:

  1. Allow modification of the response body · Issue #47 · spring-cloud/spring-cloud-gateway (github.com)
  2. 获取SpringCloud gateway 响应的response的值,可以查看、修改 - 腾讯云开发者社区-腾讯云 (tencent.com)
  3. gateway的ServerHttpResponseDecorator后不起作用?-有问必答-CSDN问答

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/150884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在线浏览PDF:Grapecity Documents for PDF Viewer 6.0.2

Grapecity Documents for PDF Viewer跨平台 JavaScript PDF 查看器---备注:必须配合.NET版本才能编辑PDF 使用我们的 JavaScript PDF 查看器在网络上阅读和编辑 PDF。跨浏览器和框架打开和打印。 Grapecity Documents for PDF Viewer全功能的 JavaScript PDF 查看器和 PDF 编辑…

move语言之基础学习(基本类型+表达式+变量)例子

一、基本类型 Move 的基本数据类型包括: 整型 (u8, u64, u128)、布尔型 boolean 和地址 address。 Move 不支持字符串和浮点数。 整型 整型包括 u8、u64 和 u128&#xff0c;我们通过下面的例子来理解整型&#xff1a; script { fun main() { // define empty variable, set…

python(0)计算机基础知识

文章目录计算机是什么计算机的组成计算机的使用方式windows的命令行文本文件和字符集乱码计算机是什么 在现实生活中&#xff0c;越来越无法离开计算机了 电脑、笔记本、手机、游戏机、汽车导航、智能电视。。。 计算机就是一个用来计算的机器 目前来讲&#xff0c;计算机只…

C++模板进阶+继承详解

耕耘和收获不是连贯的&#xff0c;中间还隔着很长一段时间&#xff0c;那就是坚持&#xff01;一&#xff1a;模板进阶1.1&#xff1a;非类型模板参数template<class T,size_t N> class arr { private:T _a[N]; };这里的N就跟define一样&#xff0c;属于非类型模板参数。…

MongoDB常用操作

官网地址&#xff1a;https://www.mongodb.com/docs/manual/reference/method/Date/ 实例&#xff1a;系统上运行的进程及节点集&#xff0c;一个实例可以有多个库&#xff0c;默认端口 27017。如果要在一台机器上启动多个实例&#xff0c;需要设置不同端口和不同的dbpath。库&…

第四章web服务器之httpd

文章目录第四章 web服务器1.1 www简介1.1.1 网址及HTTP简介1.1.2 HTTP协议请求的工作流程1.2 www服务器的类型1.2.1 仅提供用户浏览的单向静态网页1.2.2 提供用户互动接口的动态网站1.3 www服务器的基本配置1.4 实验1.4.1 搭建静态网站——基于http协议的静态网站1.4.2 搭建静态…

Acwing---1211.蚂蚁感冒

蚂蚁感冒1.题目2.基本思想3.代码实现1.题目 长 100 厘米的细长直杆子上有 nnn 只蚂蚁。 它们的头有的朝左&#xff0c;有的朝右。 每只蚂蚁都只能沿着杆子向前爬&#xff0c;速度是 1 厘米/秒。 当两只蚂蚁碰面时&#xff0c;它们会同时掉头往相反的方向爬行。 这些蚂蚁中…

C语言基本数据类型(一)

文章目录 前言 一、int类型 二、八进制和十六进制 三、其他整数类型 四、char 类型 五、_Bool 类型 六、 可移植类型&#xff1a;stdint.h和unttypes.h 前言 C语言基本数据类型包括声明变量、如何表示字面值常量&#xff0c;以及经典的用法。 一、int类型 C语言中包括许…

【openGauss】在openEuler(ARM架构)上安装openGauss(一主一备)

一、系统版本介绍 当前案例中的openGauss安装&#xff0c;底层操作系统为openEuler-20.03-LTS版本&#xff0c;当前openGauss对Python版本兼容性最好的是Python 3.6版本与Python 3.7版本&#xff0c;该实验使用的openEuler版本自带Python 3.7.4&#xff0c;不需要再自行安装 二…

零基础如何入门网络安全?2023年最新,建议收藏!

前言 最近收到不少关注朋友的私信和留言&#xff0c;大多数都是零基础小友入门网络安全&#xff0c;需要相关资源学习。其实看过的铁粉都知道&#xff0c;之前的文里是有过推荐过的。新来的小友可能不太清楚&#xff0c;这里就系统地叙述一遍。 01.简单了解一下网络安全 说白…

前端必会手写面试题合集

实现Event(event bus) event bus既是node中各个模块的基石&#xff0c;又是前端组件通信的依赖手段之一&#xff0c;同时涉及了订阅-发布设计模式&#xff0c;是非常重要的基础。 简单版&#xff1a; class EventEmeitter {constructor() {this._events this._events || ne…

电力系统IEEE33节点Simulink仿真研究(Matlab实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f389;作者研究&#xff1a;&#x1f3c5;&#x1f3c5;&#x1f3c5;主要研究方向是电力系统和智能算法、机器学…

arduino基本知识认识和学习资源

个人对ardunio的感觉 **像是一个模块化功能的单片机&#xff0c;编程时在单片机中就像python在计算机语言的感觉。**硬件方面的功能比较单一依赖于传感器和硬件电路&#xff1b;编程比较简单&#xff0c;所有执行的函数都已经被封装&#xff0c;所以想要成为第一个用这个库吃瓜…

【C语言刷题】猜名次、猜凶手、杨辉三角、杨氏矩阵、字符串左旋、判断是否为左旋子串

目录 一、猜名次 二、猜凶手 三、杨辉三角 解法一&#xff1a; 解法二 四、杨氏矩阵 解法一 解法二 五、字符串左旋 解法一 解法二 六、判断是否为字符串左旋字串 解法一 解法二 总结 一、猜名次 5位运动员参加了10米台跳水比赛&#xff0c;有人让他们预测比赛结果…

基于轻量级CNN开发构建学生课堂行为识别系统

其实早在之前&#xff0c;我的一些文章里面就有做过关于学生课堂行为检测识别的项目&#xff0c;感兴趣的话可以自行移步阅读&#xff1a;《yolov4-tiny目标检测模型实战——学生姿势行为检测》《基于yolov5轻量级的学生上课姿势检测识别分析系统》这些主要是偏目标检测类的项目…

Raft论文阅读

Raft 论文阅读 参考&#xff1a; Raft Paper 一文搞懂Raft算法 - xybaby Raft Demo Raft 实现汇总 Raft 为什么是更易理解的分布式一致性算法 空挡) Raft协议实现之etcd(一)&#xff1a;基本架构 Raft 协议 - buttercup 【raft】学习二&#xff1a;etcd/raft raft数据结构学…

第四十八讲:神州路由器IPv6静态路由配置

实验拓扑图如下所示 配置步骤&#xff1a; 步骤1&#xff1a;配置R1接口 R1_config#ipv6 unicast-routing //启用IPv6路由 R1_config#in g0/4 R1_config-_g0/4#ipv6 address 2001:10::1/64 //手工配置IPv6地址 R1_config-…

LInux背景【Linux】

一、技术推动社会发展的基本动力作为万物之长的人类&#xff0c;我们相较于其他的生物哪里是特殊的&#xff1f;举一个例子&#xff1a;老虎需要几千上万年进化来的爪子&#xff0c;人类可以在更短的时间内通过制造石矛石斧这类工具变可以模拟。通过这一个例子我们得出——人的…

python自学之《21天学通Python》(7)

第10章 Python进阶话题 10.1 函数与命名空间 Python中可以通过模块来管理复杂的程序&#xff0c;而将不同功能的函数分布在不同的模块中&#xff0c;那么函数及其全局命名空间决定了函数中引用全局变量的值。函数的全局命名空间始终是定义该函数的模块&#xff0c;而不是调用该…

java面试之Spring篇

一、Spring概述 1. Spring由哪些模块组成 spring core&#xff1a;提供了框架的基本组成部分&#xff0c;包括控制反转&#xff08;Inversion of Control&#xff0c;IOC&#xff09;和依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;功能。spring beans…