Gateway学习笔记一 responseBody和resquestBody的获取 您所在的位置:网站首页 databufferfactory Gateway学习笔记一 responseBody和resquestBody的获取

Gateway学习笔记一 responseBody和resquestBody的获取

2023-05-25 11:33| 来源: 网络整理| 查看: 265

1 引言

笔者在实现开发者服务网关模块的任务过程中,遇到下列需求(有关requestBody和responseBody部分):

对所有的请求,取出requestBody作为参数,调用鉴权接口 不影响requsetBody前提下,路由转发 从路由转发的回复中取出responseBody,作为参数调用统计接口

gateway的工作流程如图,filter的传递中,我们通常用ServerWebExchange来获取请求、回复、相关参数等。

我最初的思路,想当然地希望从ServerWebExchange中直接使用exchange.getXXX()方法获取body,

 

然而实际上从exchange中无法读取具体的requestBody和responseBody。

 

 

 

2 原因分析 2.1 ServerWebExchange

ServerWebExchange命名为服务网络交换器,存放着重要的请求-响应属性、请求实例和响应实例等等,有点像Context的角色

 

注意到ServerWebExchange.mutate()方法,通过使用decorator将exchange重新包装起来。

ServerWebExchange实例可以理解为不可变实例,如果我们想要修改它,需要通过mutate()方法生成一个新的实例

 

 

2.2 ServerHttpRequest

ServerHttpRequest实例是用于承载请求相关的属性和请求体。Spring Cloud Gateway中底层使用Netty处理网络请求,通过追溯源码,可以从ReactorHttpHandlerAdapter中得知ServerWebExchange实例中持有的ServerHttpRequest实例的具体实现是ReactorServerHttpRequest

ReactorServerHttpRequest的父类AbstractServerHttpRequest中初始化内部属性headers的时候把请求的HTTP头部封装为只读的实例,所以不能直接从ServerHttpRequest实例中直接获取请求实例并且进行修改。

 

如果要修改,需要使用2.1中提到的mutate方法重新包装生成一个新实例,具体的实现在下面介绍。

 

3 解决方案 3.1 基于ReadBodyPredicateFactory的实现

ReadBodyPredicateFactory源码指出,body只允许从request中读取一次,再次读取时会抛异常。因此对于已经读取过的requestBody,为了不影响后期,需要对请求体内容进行二次包装,即第一次读取内容进行缓存,后面对同个请求体的读取则直接返回缓存内容。

 

下面是router提供的body读取方法,其中bodyToMono方法我们可以拿到完整的body内容,并返回指定类型inClass,body即为读取到的请求体内容对应的数组。

下面是仿照ReadBodyPredicateFactory的方式获取body的解决方案。 1 public final List


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有