'Spring webflux webfilter removes the body from the request
I have a filter created where I access the body of the payload and do some logic on it (for now let's say I log the body). In the last step, I return Mono but when the request proceeds through the controller to services it throws a bad request error that the body is missing.
Code for the filter:
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
HttpHeaders headers = serverWebExchange.getRequest().getHeaders();
String domain = headers.getFirst("domain");
return serverWebExchange.getRequest().getBody()
.single()
.flatMap(body -> Mono.just(parseBody(body)))
.flatMap(s -> webFilterChain.filter(serverWebExchange));
}
private String parseBody(DataBuffer fbody) {
System.out.println("parsing body");
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
Channels.newChannel(baos).write(fbody.asByteBuffer().asReadOnlyBuffer());
} catch (IOException e) {
e.printStackTrace();
}
return baos.toString(StandardCharsets.UTF_8);
}
The error: org.springframework.web.server.ServerWebInputException: 400 BAD_REQUEST "Request body is missing"
What can cause this behavior?
Solution 1:[1]
The reason is that you can only read the body once (https://github.com/spring-cloud/spring-cloud-gateway/issues/1587)
You are reading it here: serverWebExchange.getRequest().getBody() and therefore it is omitted in the request.
A solution is to cache the body, you can use for instance the ReadBodyRoutePredicateFactory (https://github.com/spring-cloud/spring-cloud-gateway/issues/1307).
Make sure the RemoveCachedBodyFilter is enabled so the body is released so you do not have memory leaks.
Solution 2:[2]
So It seems I found solution its kinda hack, but still working.
UIInputView on init have inputViewStyle which mimics the keyboard background. If use UIInputView as parent view for UIToolbar with a clear background color, we will be good. Or use UIInputView itself, and add buttons on it, and apply it on inputAccessoryView without UIToolbar.
It depends on your content and future needs.
Example of keyboard what will shows: toolbar with right color implemented
My example with UIToolbar as subclass you can implement variant you want:
//add toolbar
UIToolbar* toolbar = [[UIToolbar alloc] init];
[toolbar sizeToFit];//get height for toolbar
CGFloat width = [UIScreen mainScreen].bounds.size.width;//set width for toolbar
CGRect frame = toolbar.frame;
frame.size.width = width;
toolbar.frame = frame;
//toolbar buttons setting
UIBarButtonItem *spaceBarButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil action:nil]; // to make close button on right side
UIBarButtonItem *closeBarButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemClose
target:textField action:@selector(endEditing:)];
toolbar.items = @[spaceBarButton, closeBarButton];
//make toolbar background clear color
[toolbar setBackgroundImage:[UIImage new]
forToolbarPosition:UIToolbarPositionAny
barMetrics:UIBarMetricsDefault];
[toolbar setBackgroundColor:[UIColor clearColor]];
//creating UIInputView for using its background color
UIInputView *inputView = [[UIInputView alloc] initWithFrame:toolbar.bounds inputViewStyle:UIInputViewStyleKeyboard];
// UIInputViewStyleKeyboard - view mimics the keyboard background
[inputView addSubview:toolbar];
textField.inputAccessoryView = inputView;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | GuyT |
| Solution 2 | Lauva |
