I am using spring boot version - 2.0.6.RELEASE and spring cloud version - Finchley.SR2
and i have created my custom gateway filter to modify the request body.
but while converting the request body to string using Flux i am getting a empty string. i need a method to get the string corresponding to my request body.
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = (ServerHttpRequest) exchange.getRequest();
String s = resolveBodyFromRequest(request);
/* s comes out to be "" */
return chain.filter(newExchange);
}
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest){
//Get the request body
Flux<DataBuffer> body = serverHttpRequest.getBody();
StringBuilder sb = new StringBuilder();
body.subscribe(buffer -> {
byte[] bytes = new byte[buffer.readableByteCount()];
buffer.read(bytes);
DataBufferUtils.release(buffer);
String bodyString = new String(bytes, StandardCharsets.UTF_8);
sb.append(bodyString);
});
return sb.toString();
}
You could use the ModifyRequestBodyGatewayFilterFactory which I believe is included in Spring Cloud Gateway 2.0.2 which is part of Finchley.
For Ex:
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ModifyRequestBodyGatewayFilterFactory.Config modifyRequestConfig = new ModifyRequestBodyGatewayFilterFactory.Config()
.setContentType(ContentType.APPLICATION_JSON.getMimeType())
.setRewriteFunction(String.class, String.class, (exchange1, originalRequestBody) -> {
String modifiedRequestBody = yourMethodToModifyRequestBody(originalRequestBody);
return Mono.just(modifiedRequestBody);
});
return new ModifyRequestBodyGatewayFilterFactory().apply(modifyRequestConfig).filter(exchange, chain);
};
}
This is another approach work in spring cloud gateway 2.2.5, we will use ReadBodyPredicateFactory, as this will cache requestBody to ServerWebExchange with attribute key cachedRequestBodyObject
create always true Predicate
@Component
public class TestRequestBody implements Predicate
{
@Override
public boolean test(Object o)
{
return true;
}
}
in application.yml, add Predicate
spring:
cloud:
gateway:
routes:
....
predicates:
.....
- name: ReadBodyPredicateFactory
args:
inClass: "#{T(String)}"
predicate: "#{@testRequestBody}"
in your own filter, get requestBody like below:
@Override
public GatewayFilter apply(Object config)
{
return (exchange, chain) -> {
String requestBody = exchange.getAttribute("cachedRequestBodyObject");
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With