springcloud gateway 获取post请求体Json分段导致不全的解决方案

本文介绍了在SpringBoot 2.0.8.RELEASE + SpringCloud Finchley.SR2 + Spring Cloud Gateway环境下,遇到从POST请求体中获取Json数据时出现分段不全的问题。通过尝试不同方式读取请求体,如Flux订阅和StringBuilder拼接,发现仍存在不完整的情况。最后通过RouteLocator的readBody方法结合filter,利用`exchange.getAttribute("cachedRequestBodyObject")`成功获取完整请求体,解决了问题。然而,对于YML配置路由的类似问题,文中提到仍需要进一步排查解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


开发版本
springboot 2.0.8.RELEASE + springcloud Finchley.SR2 + spring cloud gateway

前端客户端采用post发送请求,content_type: application/json,
spring cloud gateway需要从request的中取出body进行网关的鉴权处理,然后把处理之后的数据重新封装到body中转发给下游业务系统,
最之前的方式采用的是以下方式读取请求体:
 AtomicReference<String> bodyRef = new AtomicReference<>();//缓存读取的request body信息
               Flux<DataBuffer> fluxBody = exchange.getRequest().getBody();
               fluxBody.subscribe(buffer -> {
                     CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
                     DataBufferUtils.release(buffer);
                     bodyRef.set(charBuffer.toString());
               });
               String bodyStr = bodyRef.get();


偶尔前端提出验签失败,检查上送请求体报文时发现错误:网关获取的body不完整。

尝试了网上的写法来获取body,于是改成了以下的写法来亲自验证,偶尔还是发现网关获取的body体不完整,说明此方法还是不行,有坑。

    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest){
 

Spring Cloud Gateway 是一个反向代理和路由器,它可以拦截进入的请求并将它们路由到同的服务。Spring Cloud Gateway 可以通过以下步骤获取请求体: 1. 在 Spring Cloud Gateway 的路由配置中,定义一个过滤器: ```java @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("path_route", r -> r.path("/foo/**") .filters(f -> f.filter(new RequestBodyFilter())) .uri("http://localhost:8080")) .build(); } ``` 这里定义了一个名为 `RequestBodyFilter` 的过滤器,用于获取请求体。 2. 实现 `RequestBodyFilter` 过滤器: ```java public class RequestBodyFilter implements GatewayFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return exchange.getRequest().getBody() .flatMap(body -> { // 处理请求体 byte[] bytes = new byte[body.readableByteCount()]; body.read(bytes); String requestBody = new String(bytes); System.out.println(requestBody); // 重新设置请求体 DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes); exchange.getRequest().mutate().body(buffer); return chain.filter(exchange); }); } } ``` 这里的 `filter` 方法会获取请求体,并进行处理。处理完成后,需要重新设置请求体,以便后续的过滤器或路由器可以正确地处理请求。 3. 在请求中发送请求体: ```bash curl -X POST http://localhost:8080/foo -d '{"name": "John"}' ``` 这里使用 `curl` 命令发送一个 POST 请求,并在请求体中包含 JSON 数据。Spring Cloud Gateway 会拦截这个请求,并使用定义的过滤器获取请求体。 以上就是 Spring Cloud Gateway 获取请求体的方法。需要注意的是,获取请求体可能会影响性能,因此应该谨慎使用。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值