标签:return chain exchange Spring request ServerHttpRequest filter Gateway Cloud
简介
本文使用的spring cloud版本:2020.0.1
关于Spring Cloud Gateway报文获取,网上写法较多参考ModifyRequestBodyGatewayFilterFactory,经过非严谨测试其性能下降剧烈。
本文同样参考Spring Cloud Gateway源码,只不过参考的是ReadBodyRoutePredicateFactory,经过非严谨测试该方式性能会下降20%-30%,性能相较上述方案有了巨大提升。
写法核心逻辑(直接仿写ReadBodyRoutePredicateFactory,定义一个Filter)
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//WebFilterChain GatewayFilterChain ServerHttpRequest currentHttpRequest = exchange.getRequest(); if(logReqRespUtils.needGenerateSn(currentHttpRequest.getMethod())){ return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange,(serverHttpRequest) -> ServerRequest .create(exchange.mutate().request(serverHttpRequest).build(), messageReaders) .bodyToMono(String.class) .defaultIfEmpty("") .doOnNext(objectValue -> {
//objectValue即为请求Body内容 }) .flatMap(bodyString->{ if (serverHttpRequest == exchange.getRequest()) { return chain.filter(exchange); } //ServerWebExchangeUtils.cacheRequestBodyAndRequest中已经缓存了可重复读的request 并且request也已经转换成了可重复度的request ServerHttpRequest cacheRequest = (ServerHttpRequest)exchange.getAttributes().get(ServerWebExchangeUtils.CACHED_SERVER_HTTP_REQUEST_DECORATOR_ATTR); return chain.filter(exchange.mutate().request(cacheRequest).build()); }) ); } return chain.filter(exchange); }
简单分析
ReadBodyRoutePredicateFactory可用来对请求体内容进行判断。
如此其中一定会获取请求体。
该文件短短一百多行代码,很快就可以定位到其核心部分:
在完成request和requestBody的缓存之后,通过ServerHttpRequest创建了一个ServerRequest ,拿到请求体的字符串,之后进行判断。
查看 ServerWebExchangeUtils相关代码,显然可见:
获取了body(Flux<DataBuffer>),之后装饰了一个新的Request,在exchange中将dataBuffer(请求体)和装饰后的Request进行缓存。之后交由我们自定义的逻辑进行处理。
上图的 decorate方法中有一处 用到了Netty的retainedSlice方法:
大意就是创建了一个ByteBuf的副本,不过是同源的,改内容会彼此影响,操作索引不会彼此影响。因此可以重复读,不需要我们手动释放,最后交由Spring去释放掉。
标签:return,chain,exchange,Spring,request,ServerHttpRequest,filter,Gateway,Cloud 来源: https://www.cnblogs.com/flying607/p/15273330.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。