Spring-cloud-gateway: Howto read request body?

Created on 22 Aug 2018  路  6Comments  路  Source: spring-cloud/spring-cloud-gateway

Question

My use-case : 2 microservices behind the api gateway.

I get a route that must be route to microservice B but before the request must be routed to microservice A for some pre-check (it's not an API-Composition)

So I implemented the call to microservice A in a GatewayFilter. Config :

.route(r -> r.method(HttpMethod.GET)
                    .and()
                    .path("/messages/*")
                    .filters((f) -> f.filter(precheckfilter))
                    .uri(destinations.getEndpointX))

problem : I don't found an easy way to extract the request body (Flux of DataBuffer to Json String) and call the service 2. I got some exceptions because I used blocking method like toStream()

Where can I find some samples about filter implementation ?

I try something like this :

exchange.getRequest().getBody().map(dataBuffer -> {
         ByteSource byteSource = new ByteSource() {
          @Override
          public InputStream openStream() throws IOException {
            return dataBuffer.asInputStream();
          }
        };
        try {
          String text = byteSource.asCharSource(Charsets.UTF_8).read();
          return text;
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }).collect(Collectors.joining()).subscribe(....call service B)

but wrong....

question

All 6 comments

I simply tried this

return (exchange, chain) -> {
       ServerRequest serverRequest = new DefaultServerRequest(exchange);
       serverRequest.bodyToMono(String.class).subscribe(s -> {
         System.out.println("Request :  " + s);
       });
       return chain.filter(exchange);
     };

but seems request body is empty... don't understand what happened...

Indeed non-trivial.. ok thanks I will try this.

Client: Content_type is application/json and post request
Server: springboot 2.0.6 and spring cloud gateway Finchley.SR2
steps:
first: Server gets body from post request
second: Server uses the params to do somthing then get new params
problems: this first step sometimes cannot get full body,sometimes can work. why?
method:
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
Flux body = serverHttpRequest.getBody();
AtomicReference bodyRef = new AtomicReference<>();
body.subscribe(buffer -> {
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
DataBufferUtils.release(buffer);
bodyRef.set(charBuffer.toString());
});
return bodyRef.get();
}

For reading or modifying request body, one can simply use a filter which extends ModifyRequestBodyGatewayFilterFactory class.

`public class MyFilter extends ModifyRequestBodyGatewayFilterFactory {
@Override
public GatewayFilter apply(Config config) {
config.setRewriteFunction(String.class, String.class,
(exchange, originContent) -> {
System.out.println(originContent);
return Mono.just(originContent);
});
return super.apply(config);
}

}
`

Is it possible to easily read only the first few hundred bytes of the body without reading the whole request body, without affecting how the request is routed through to the destination? I have very large requests, and I need to do some content based routing by running a regex against a small chunk at the beginning of the body. Reading the whole body causes performance problems with the JVM/heap.

Was this page helpful?
0 / 5 - 0 ratings