SpringCloud Gateway获取post请求体(request body)
获取spring cloud gateway POST请求体的时候,会有很多坑,网上大多数解决方案是
/**
这种方法在spring-boot-starter-parent 2.0.6.RELEASE + Spring Cloud Finchley.SR2 body 中生效,
但是在spring-boot-starter-parent 2.1.0.RELEASE + Spring Cloud Greenwich.M3 body 中不生效,总是为空
*/
private 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();
}
但是实际这种解决方案(例如 这篇文章)会带来很多问题,比如request不能在其他filter中获取,会报错:
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalStateException: Only one connection receive subscriber allowed.
Caused by: java.lang.IllegalStateException: Only one connection receive subscriber allowed.
针对这种不能重复获取的问题,网上通用解决是把request重新包装,继续传递,比如 这篇文章的解决方案。
但是这种方案还会带来request body获取不完整,只能获取1024B的数据,这个问题暂时没有很好的解法,很头痛,在给官方提issues的时候,issues709 和issues707 的时候,对方让我参看一个类ModifyRequestBodyGatewayFilterFactory.java,说真的并没有看懂,最后翻源码的时候,发现了一个预言类,ReadBodyPredicateFactory ,发现里面缓存了request body的信息,于是在自定义router中配置了ReadBodyPredicateFactory,然后在filter中通过cachedRequestBodyObject缓存字段获取request body信息,这种解决,一不会带来重复读取问题,二不会带来requestbody取不全问题。三在低版本的Spring Cloud Finchley.SR2也可以运行。
step 1:现在自动以router里面配置ReadBodyPredicate预言类:
RouteLocatorBuilder.Builder serviceProvider = builder.
routes().route("gateway-sample",r -> r.readBody(Object.class, requestBody -> {log.info("requestBody is {}", requestBody);// 这里不对body做判断处理return true;}).and().path("/service").filters(f -> {f.filter(requestFilter);return f;}).uri("http://127.0.0.1:8009"));RouteLocator routeLocator = serviceProvider.build();
step2:在自定义filter中获取缓存了的request body:
Object requestBody = exchange.getAttribute("cachedRequestBodyObject");
至此问题解决,完整代码在我的github上面。https://github.com/xiaozhilia...
参考:
http://blog.51cto.com/thinkli...
https://www.cnblogs.com/cafeb...
https://blog.csdn.net/tianyal...
SpringCloud Gateway获取post请求体(request body)相关推荐
- Springcloud gateway获取post请求内容
找了很多教程,可由于各种原因(主要是Spring Boot和Spring Cloud版本不同),获取一直有问题,参考过的教程: https://windmt.com/2019/01/16/spring ...
- 获取【请求体】数据的3种方式 request.getInputStream() request.getInputStream() request.getReader()
https://www.cnblogs.com/cs-lcy/p/10431105.html
- java post 请求体构建_java – 从HttpServletRequest获取POST请求体
我试图从HttpServletRequest对象获取整个身体. 我正在关注的代码如下所示: if ( request.getMethod().equals("POST") ) { ...
- php 打印请求体,php如何获取原生请求体
php 常见问题及解决方法 (1)请求要素是json字符串,后台如何获取 //this is a common php library by huangwei , //date:2014-07-03 ...
- Request(请求继承体系,获取请求行,请求头,请求体和通用的获取请求数据和解决乱码问题)
Request(请求继承体系,获取请求行,请求头,请求体和通用的获取请求数据和解决乱码问题) 1.Request(请求) Request继承体系 要想了解RequestFacade中都提供了哪些方法, ...
- Tornado请求分析request, 获取请求参数
全栈工程师开发手册 (作者:栾鹏) 架构系列文章 请求分析request WEB请求的那些事 这节中,我们来根据客户请求报文中的请求行(Request line) ,请求头部(Request Head ...
- java http head 请求_http请求头header、请求体body、请求行介绍
HttpServletRequest对象代表客户端的请求,当客户端通过http协议请求访问 服务器的时候,http请求头的所有信息都封装在这个对象中,通过这个对象,可以获取客户端请求的所有信息.htt ...
- http请求头header、请求体body、请求行介绍
HttpServletRequest对象代表客户端的请求,当客户端通过http协议请求访问 服务器的时候,http请求头的所有信息都封装在这个对象中,通过这个对象,可以获取客户端请求的所有信息.htt ...
- HTTP请求(Request)详解
# HTTP请求(Request) ''' 当用户通过浏览器访问某个网站时, 浏览器会向网站服务器发送请求,这个请求就叫做HTTP请求. 请求包含的内容主要有: 请求方法(Request Method ...
最新文章
- 异常处理与MiniDump详解(3) SEH(Structured Exception Handling)
- SpringMVC如何实现restful接口
- 分享Kali Linux 2016.2第41周镜像虚拟机
- 《js高级程序设计》6.1.1-6.1.3——数据属性、访问器属性
- 余世维《职业经理人常犯的错误》[文字版]
- python加颜色_python字符串加颜色显示
- 《TensorFlow 2.0深度学习算法实战教材》学习笔记(三、TensorFlow 基础)
- 一段实现分页的存储过程
- Adobe-CC-2017 安装教程
- 理解景深(Depth of Field)
- origin画图畸变
- Sublime Text3轻量型跨平台C/C++开发环境(上) 安装使用篇
- Android 系统广播(大全)
- python 微信机器人教程_Python创建微信机器人(附赠Python视频教程)
- 设置BIOS从USB启动!
- Win10+vs2017跑yolov3
- 人脑认知计算模型简介(上)
- 罗斯蒙特8800DF020SA3E1D1K3M5R10涡街流量计
- Halcon OCR字符识别
- 网络断了,咫尺还是咫尺,天涯还是天涯
热门文章
- BZOJ 2246 [SDOI2011]迷宫探险 (记忆化搜索)
- 一个不错的iteye_BLOG(短裤党)
- 工具类|快递物流的订阅与查询
- “在线Excel文档编辑系统”新手开发训练营开营啦,完全免费,欲报从速!
- 烤仔说元宇宙 | 游戏还是元宇宙傻傻分不清楚?
- Deepin启动错误emergency mode解决
- 配置服务器代理【setupProxy】代理http-proxy-middleware
- 写【Python折线图】的一百个技巧(一、生成折线图网页)
- [滴滴笔试]java岗
- CSS 高级属性之 text-shadow 详解