网上的代码千奇百怪,这个是我测试后整理的。

当前端请求不含body时,也能兼容。

1.读取body流进行缓存

/*** 获取body请求数据(解决流不能重复读取问题)* 这个过滤器的order设置的是Ordered.HIGHEST_PRECEDENCE,即最高优先级的过滤器。* 优先级设置这么高的原因是某些系统内置的过滤器可能也会去读body,* 这样就会导致我们自定义过滤器中获取body的时候报body只能读取一次这样的错误* @author yuchen*/
@Slf4j
@Component
public class CacheRequestFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();if (request.getHeaders().getContentType() == null) {return chain.filter(exchange);}HttpMethod method = request.getMethod();if (method == null || method.matches("GET") || method.matches("DELETE")) {return chain.filter(exchange);}//当body中没有缓存时,只会执行这一个拦截器, 原因是fileMap中的代码没有执行,所以需要在波多野为空时构建一个空的缓存DefaultDataBufferFactory defaultDataBufferFactory = new DefaultDataBufferFactory();DefaultDataBuffer defaultDataBuffer = defaultDataBufferFactory.allocateBuffer(0);//构建新数据流, 当body为空时,构建空流Flux<DataBuffer> bodyDataBuffer = exchange.getRequest().getBody().defaultIfEmpty(defaultDataBuffer);return DataBufferUtils.join(bodyDataBuffer).flatMap(dataBuffer -> {DataBufferUtils.retain(dataBuffer);Flux<DataBuffer> cachedFlux = Flux.defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {@Overridepublic Flux<DataBuffer> getBody() {return cachedFlux;}};//exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, cachedFlux);return chain.filter(exchange.mutate().request(mutatedRequest).build());});}@Overridepublic int getOrder() {return Ordered.HIGHEST_PRECEDENCE;}}

2.从缓存读取body,就可以重复读:

    private static String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {// 获取请求体Flux<DataBuffer> body = serverHttpRequest.getBody();AtomicReference<String> bodyRef = new AtomicReference<>();body.subscribe(buffer -> {CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());DataBufferUtils.release(buffer);bodyRef.set(charBuffer.toString());});return bodyRef.get();}

SpringCloud-Gateway自定义过滤器,解决body流不能重复读的问题相关推荐

  1. 数据库隔离级别解决脏读、不可重复读、幻读

    一.脏读.不可重复读.幻读 脏读 读取了未提交的事务. 事务A读取了事务B中尚未提交的数据.如果事务B回滚,则A读取使用了错误的数据. 解决:如果一个事务在读的时候,禁止读取未提交的事务. 不可重复读 ...

  2. mysql脏读解决方案_MySQL为什么可以解决脏读和不可重复读?

    一般是通过锁机制,解决掉不可重复读和幻读的问题.是不是可以通过乐观锁的问题去解决不可重复读和幻读的问题,MySQL 采用的是 MVCC 机制来解决脏读.不可重复读的问题. MVCC 英文全称是 Mui ...

  3. 可重复读隔离级别如何解决脏读、不可重复读

    我们都知道可重复读隔离级别可以解决脏读.不可重复读.那么具体是如何解决的呢? 下面先通过实验来演示可重复读能够解决脏读.不可重复读问题,然后解释具体的原因. 环境搭建 1. 建立两个session连接 ...

  4. mysql脏读解决方案_mysql是如何解决脏读、不可重复读、幻读?

    刚开始写博客.. 写的太low. 1.数据库的两种读,每种读读的数据版本不一样,所以也称为MVCC,即多版本并发控制 a) 快照读 select * from where xxx  这种形式的都是快照 ...

  5. springcloud gateway 自定义 accesslog elk

    大家好,我是烤鸭: ​ 最近用 springcloud gateway 时,想使用类似 logback-access的功能,用来做数据统计和图表绘制等等,发现没有类似的功能,只能自己开发了. 环境: ...

  6. SpringCloud Gateway 服务网关,限流

    SpringCloud Gateway 提供了基于Redis 和lua脚本实现的令牌桶算法进行限流,即 RequestRateLimiterGatewayFilterFactory类,通过设置过滤器实 ...

  7. drools动态配置规则_微服务实战系列(八)-网关springcloud gateway自定义规则

    1. 场景描述 先说明下项目中使用的网关是:springcloud gateway, 因需要给各个网关服务系统提供自定义配置路由规则,实时生效,不用重启网关(重启风险大),目前已实现:动态加载自定义路 ...

  8. SpringCloud Gateway 通过redis实现限流

    前言 在高并发的系统中,往往需要在系统中做限流,一方面是为了防止大量的请求使服务器过载,导致服务不可用,另一方面是为了防止网络攻击. 常见的限流方式,比如Hystrix适用线程池隔离,超过线程池的负载 ...

  9. SpringCloud Gateway 通过redis实现限流【SpringCloud系列8】

    SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见. 程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCl ...

最新文章

  1. 分布式CAP中情侣的纠缠故事,真是剪不断 理还乱!
  2. iOS并行程序开发- GCD NSOperationQueue(1)
  3. uva 12563——Jin Ge Jin Qu hao
  4. javascript中对变量类型的推断
  5. MVI - 继续来凑个热闹
  6. 今天写了个商品采购入得存储过程,使用游标实现的,实现了多个商品库存的增加...
  7. 四阶龙格库塔法程序c语言,四阶龙格库塔法
  8. Java源码-猜数字小游戏(Swing编程版)
  9. springboot面试题
  10. 柯尼卡美能达c353改语言,柯尼卡美能达bizhub c353c253c203维修手册中文部分2.pdf
  11. 何小鹏快跑:身家暴涨50亿美元,他还愿坐经济舱吗?
  12. 弗洛伊德的乌龟与兔子
  13. 华为手机鸿蒙切换主页,京东APP可一键切换“华为鸿蒙版界面”:简洁多了
  14. 故乡的原风景-宗次郎
  15. Java之Snake历程
  16. 工程师的浪漫:用机械臂画一个爱心
  17. 孕期、哺乳期吃海鲜注意事项----一洲服务
  18. 测试工程师面试汇总【完美世界】
  19. 笔记三:ASP.NET MVC 添加一个新页面,运行显示HTTP 404。您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用。请检查以下 URL 并确保其拼写正确。
  20. R语言独立性检验-基础

热门文章

  1. 通过RPM包离线安装Clickhouse 20.3(LTS版本)
  2. 屌丝向女神示爱,不料女神会Java,微微改动代码,把屌丝憋死了…
  3. 今天我们来聊聊:MD5 到底是不是加密?
  4. vmware 配置host-only ip
  5. 限制文本行数,CSS文本溢出省略号,及兼容火狐
  6. 浏览器缓存机制(HTTP缓存机制)
  7. 商业银行贷款业务电子签:防范萝卜章-保存证据链-安全高效放款
  8. 【机器学习】分类决策树与回归决策树案例
  9. Python解压zip文件出现TypeError: pwd: expected bytes, got str的解决方案
  10. 人工智能算法背后的「至强」后盾