SC-Gateway缓存Body并从中提取FormData和MultiPart

更新于 2021年3月12日

新增具体实例,感谢yvanbaker指出的Part文件上传读取问题

示例

通过创建一个XSS过滤的全局过滤器,来展示form-data,part,及url的过滤操作。

缓存Body

在SCG 2.1.4+,支持body题缓存为DataBuffer,去掉了外面的Flux包装,具体可以参考ServerWebExchangeUtils#cacheRequestBody

那下面就用2.1.1的SCG来做,把body缓存拿到低版本来试试。

新建一个GlobalFilter做缓存,把所有操作都封装到BodyUtils.cacheRequestBody

1
2
3
4
5
6
return BodyUtils.cacheRequestBody(exchange, (serverHttpRequest) -> {
if (serverHttpRequest == exchange.getRequest()) {
return chain.filter(exchange);
}
return chain.filter(exchange.mutate().request(serverHttpRequest).build());
});

XSS过滤

  1. 先从Attribute中取到缓存的Databuffer
  2. 分别针对header,query,form-data,multipart做过滤操作
  3. 重新封装请求,返回给过滤链(Filter Chain)

具体内容可以查看demo:escape-request


以下为旧内容,不推荐

缓存Body

缓存Body的话, Gateway给出了一个工厂类,可以直接用。也可以像我有别的需求的,重写一下。

我主要就给他改成GlobalFilter,然后给了最高优先级,就想在入口处就拿到缓存内容,放到Attribute中,以供后面使用。

给一个Gist的链接吧 : Link

提取数据

困扰我好久的问题主要就是FormDataPart的使用问题,因为需要做参数映射、Hash计算等操作,需要用到这些body中的内容,也不能直接拿Body去计算,还是需要转换为标准的Data格式,比如FormData主要就是键值对,MultiPart主要就是上传文件,然后给他转成输入流InputStream.

Body转换

本来还提了一个issues #671 , 但是因为没有给完整demo而是给了一个Gist就被关了(笑,确实是自己懒省事了). 但是今儿在rebuild demo的时候想到,既然我都已经拿到了Body,直接转换一下不就行了么,也解决了Mono形式的FormData被消费,后端服务无法接收的问题。

当我发现了BodyExtractors类, 其中有toFormData()toMultipartData()方法, 结合测试类BodyExtractorsTests 就可以实现提取了

Gist : Link

完整Demo-FormData :zip

结束!🔚


Buy Me A Coffee.