这个filter 中报Only one connection receive subscriber allowed.

主要是body体为null的情况

@Component
public class DecryptionFilter implements GlobalFilter, Ordered {

@SneakyThrows
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

解决办法:

参考:https://blog.csdn.net/weixin_37644979/article/details/115264027

完全代码:

package com.riocento.filter;import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBufAllocator;import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.CoreSubscriber;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Iterator;/*** 解密过滤器* 对请求的request进行解密*/
@Slf4j
@Component
public class DecryptionFilter implements GlobalFilter, Ordered {@SneakyThrows@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("request解密处理");//源request对象ServerHttpRequest request = exchange.getRequest();//获取请求方式HttpMethod method = request.getMethod();URI uri = request.getURI();log.info("请求方式:"+method);log.info("请求地址:"+uri);MultiValueMap<String, String> queryParams = request.getQueryParams();log.info("所有参数:"+queryParams);//是否为加密参数Boolean isEncrypt = false;// GET请求解密if(HttpMethod.GET == method){if(queryParams.containsKey("isEncrypt")){isEncrypt = Boolean.valueOf(queryParams.get("isEncrypt").get(0));}if(isEncrypt){//加密参数String enParams = queryParams.get("enParams").get(0);//将参数解密String paramsStr = AESUtil.decrypt(enParams);//格式化参数String urlParams = formatUrlParams(paramsStr);//重新创建requestURI plaintUrl = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), urlParams, uri.getFragment());ServerHttpRequest newRequest = request.mutate().uri(plaintUrl).build();return chain.filter(exchange.mutate().request(newRequest).build());}}//POST和PUT请求解密else if(HttpMethod.POST == method|| HttpMethod.PUT == method) {if(queryParams.containsKey("isEncrypt")){isEncrypt = Boolean.valueOf(queryParams.get("isEncrypt").get(0));}if(isEncrypt){URI plaintUrl = null;//处理url参数if(queryParams.size() > 0 && queryParams.containsKey("enParams")){//加密参数String urlEnParams = queryParams.get("enParams").get(0);//将参数解密String urlParamsStr = AESUtil.decrypt(urlEnParams);//格式化参数String urlParams = formatUrlParams(urlParamsStr);//重新创建uriplaintUrl = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), urlParams, uri.getFragment());}else{plaintUrl = uri;}//处理表单参数//获取表单信息Flux<DataBuffer> dataBufferFlux = request.getBody();//获取body中的数据String strBody = FilterRequestResponseUtil.resolveBodyFromRequest(dataBufferFlux);//获取加密参数String enParams = getEnParams(strBody);//将参数解密String paramsStr = AESUtil.decrypt(enParams);ServerHttpRequest newRequest = request.mutate().uri(plaintUrl).build();DataBuffer bodyDataBuffer = stringBuffer(paramsStr);if(paramsStr == null) {newRequest = new ServerHttpRequestDecorator(newRequest) {@Overridepublic Flux<DataBuffer> getBody() {return Flux.just(bodyDataBuffer);}};// 构建新的请求头HttpHeaders headers = new HttpHeaders();headers.putAll(exchange.getRequest().getHeaders());// 重新设置CONTENT_LENGTHint length = 0;headers.remove(HttpHeaders.CONTENT_LENGTH);headers.setContentLength(length);newRequest = new ServerHttpRequestDecorator(newRequest) {@Overridepublic HttpHeaders getHeaders() {return headers;}};return chain.filter(exchange.mutate().request(newRequest).build());}Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);newRequest = new ServerHttpRequestDecorator(newRequest) {@Overridepublic Flux<DataBuffer> getBody() {return bodyFlux;}};// 构建新的请求头HttpHeaders headers = new HttpHeaders();headers.putAll(exchange.getRequest().getHeaders());// 重新设置CONTENT_LENGTHint length = paramsStr.getBytes().length;headers.remove(HttpHeaders.CONTENT_LENGTH);headers.setContentLength(length);newRequest = new ServerHttpRequestDecorator(newRequest) {@Overridepublic HttpHeaders getHeaders() {return headers;}};return chain.filter(exchange.mutate().request(newRequest).build());}}//DELETE等请求方式不做处理return chain.filter(exchange);}@Overridepublic int getOrder() {return 0;}/*** 格式化url参数* @param paramsStr 字符串参数*/private String formatUrlParams(String paramsStr){StringBuilder stbResult = new StringBuilder();if(Strings.isNotEmpty(paramsStr)){if(paramsStr.startsWith("{")){JSONObject paramsJSON = JSONObject.parseObject(paramsStr);Iterator<String> iterator = paramsJSON.keySet().iterator();while (iterator.hasNext()) {String key = iterator.next();String value = paramsJSON.getString(key);if(stbResult.length() > 0){stbResult.append("&");}stbResult.append(key).append("=").append(value);}}else{stbResult.append(paramsStr);}}return stbResult.toString();}/*** 获取加密字符串参数* @return*/private String getEnParams(String paramsStr){String result = null;if(Strings.isNotEmpty(paramsStr)){if(paramsStr.startsWith("{")){//将字符串转换为JSON格式JSONObject jsonBody = JSONObject.parseObject(paramsStr);result = jsonBody.getString("enParams");}else if(paramsStr.indexOf("=") > 0){String[] paramsArr = paramsStr.split("=");result = paramsArr[1];}}return  result;}private DataBuffer stringBuffer(String value) {if(value == null) {NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(0);return buffer;}byte[] bytes = value.getBytes(StandardCharsets.UTF_8);NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);buffer.write(bytes);return buffer;}
}

Only one connection receive subscriber allowed.相关推荐

  1. spring cloud gateway Unhandled failure: Only one connection receive subscriber allowed.

    https://gist.github.com/WeirdBob/b25569d461f0f54444d2c0eab51f3c48 ToUppercaseGlobalFilter.java https ...

  2. Spring Cloud Gateway 之获取请求体的几种方式

    一.直接在全局拦截器中获取 伪代码如下 private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest){Flux& ...

  3. spring cloud gateway - 日志

    spring cloud gateway - 日志 实现日志 前提:spring cloud gateway是基于webflux的项目,所以不能像使用spring mvc一样直接获取request b ...

  4. SpringCloud Gateway获取post请求体(request body)

    获取spring cloud gateway POST请求体的时候,会有很多坑,网上大多数解决方案是 /** 这种方法在spring-boot-starter-parent 2.0.6.RELEASE ...

  5. quartz异常:Couldn't rollback jdbc connection

    为什么80%的码农都做不了架构师?>>>    最近工作发现,有个项目偶尔会报Couldn't rollback jdbc connection. No operations all ...

  6. python2.0_s12_day10_rabbitMQ使用介绍

    RabbitMQ RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列(M ...

  7. Python-day-9- RabbitMQ队列

    RabbitMQ队列 安装 http://www.rabbitmq.com/install-standalone-mac.html 安装python rabbitMQ module pip insta ...

  8. Day10-Python3基础-协程、异步IO、redis缓存、rabbitMQ队列

    内容目录: Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko S ...

  9. Python学习笔记day10

    Twsited异步网络框架 twisted是一个用python语言写的事件驱动的网络框架,他支持很多种协议,包括UDP,TCP,TLS和其他应用层协议,比如HTTP,SMTP,NNTM,IRC,XMP ...

  10. java disconnect_Java BlockingConnection.disconnect方法代碼示例

    本文整理匯總了Java中org.fusesource.mqtt.client.BlockingConnection.disconnect方法的典型用法代碼示例.如果您正苦於以下問題:Java Bloc ...

最新文章

  1. C语言解析pcap文件得到HTTP信息实例(原创,附源码)
  2. 深入浅出计算机组成原理学习笔记:高速缓存(下)-你确定你的数据更新了么?(第38讲)...
  3. python 字符串split 正则分割 换行符_python数据分析实战-JOINamp;SPLIT分割与合并
  4. matlab用dft对连续信号做谱分析,用 DFT 对连续信号进行谱分析的误差问题有哪些?...
  5. 聚类算法分析及其性能比较
  6. 华为荣耀手机指令代码大全_2020.10月《各价位华为、荣耀手机推荐》
  7. Webshell实现与隐藏探究
  8. 微信小程序云函数 -- 腾讯云通用印刷体识别应用
  9. 电商产品经理:如何搭建会员管理体系(多图干货)
  10. godspeed机器人_cs1.6kz地图包下载
  11. Python】Scrapy抓取多玩Gif图片
  12. (转)男人的梦想之野性篇 什么是真正的越野车
  13. 使用SINet进行伪装目标检测
  14. HQChart--uniApp v3 中使用 render.js
  15. 软路由-Hi-Spider Router-海蜘蛛
  16. Teams认证话机系列(2)--AudioCodes C450HD
  17. 在美面试红宝书:美国MBA毕业生就业面经
  18. CSS3蒙版 Mask
  19. SSM项目实战-新闻发布系统
  20. 爬虫入门------从数据看奥斯卡陪跑健将到底是谁?学院派评委都热衷于哪类电影?

热门文章

  1. Python中的f字符串的用法
  2. VMware vCenter vShield配置vxlan时候vib未安装
  3. 联盟链系列 - 中间CA颁发证书
  4. wamp5数据库密码修改
  5. LC.1175. Prime Arrangements
  6. 【定制项目】【M13】【数据监控 + 数据分析 + 可视化大屏】- 关键技术 python flask + pandas + echarts + excel
  7. 利用FME(myfme)将MAPGIS格式的土地处用现状图完美转换为CAD
  8. 1487C - Minimum Ties
  9. 在linux系统下ping不通windows主机问题
  10. 公众号内测算法推荐引争议,却有小号因此阅读增长20倍