I have the below code where I am able to log the headers and URL. But the body() method is returning an object of type BodyInserter. In the debug mode(STS), we can see the request body object. Is there any way to log the request?
[private ExchangeFilterFunction logRequest() {
return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { loggingService.info(clientRequest.url());
loggingService.info(clientRequest.headers());
BodyInserter<?, ? super ClientHttpRequest> bodyInserters= clientRequest.body();
return Mono.just(clientRequest);
});
}
Related
**I am trying to make a POST controller in springboot having request parameter as JSON object and hiting the controller from the postman .The problem I am facing is that I want to pass a JSONObject in the parameter itself from the postman. I am sending JSON from POSTMAN in body, basically pasted JSON object in the raw body **
#RestController
public class PostController {
#PostMapping(value="/status")
public JSONObject status (#RequestBody JSONObject jsonObject){
System.out.println(jsonObject.toString());
return jsonObject;
}
}
`
I am hitting from the postman with POST request at the url : localhost:8080/status ,,
I am not getting the appropriate response. Main problem is that the JSON object is not getting passed to the request . PLease explain.
Intellij terminal response :
{}
AT line 19
and POSTMAN response is :
{
"empty": true,
"mapType": "java.util.HashMap"
}
enter image description here
I have got a situation that is needed to return HTTP 2XX when WebClient returns any kind of 4XX.
My existing code below,
public Mono<ResponseEntity<>String> postMethodA(String valueA) {
return webClient
.put()
.uri'/')
.bodyValue(valueA)
.retrieve()
.toEntity(String.class);
}
I added onStatus method like this.
public Mono<ResponseEntity<>String> postMethodA(String valueA) {
return webClient
.put()
.uri'/')
.bodyValue(valueA)
.retrieve()
.onStatus(HttpStatus::is4XXClientError response -> Mono.empty())
.toEntity(String.class);
}
If I added
onStatus(HttpStatus::is4XXClientError response -> Mono.empty())
still, it is not gonna work because it is not able to return 2XX.
Is there a way to change the Http status when returning the response? and can you please show some example?
To ignore an error response completely, and propagate neither response
nor error, use a filter, or add onErrorResume downstream, for example:
webClient.get()
.uri("https://someUrl.com/account/123")
.retrieve()
.bodyToMono(Account.class)
.onErrorResume(WebClientResponseException.class,
ex -> ex.getRawStatusCode() == 404 ? Mono.empty() : Mono.error(ex));
Reference: JavaDoc
I am using Spring WebClient to call REST API. I want to throw an error based on the response. For example, if there is an error (400) with body
{"error": "error message1 "}
then I want to throw an error with "error message1". Same way if there is an error(400) with the body
{"error_code": "100020"}
then I want to throw an error with error_cde 100020. I want to do it in a non-blocking way.
public Mono<Response> webclient1(...) {
webClient.post().uri(createUserUri).header(CONTENT_TYPE, APPLICATION_JSON)
.body(Mono.just(request), Request.class).retrieve()
.onStatus(HttpStatus::isError, clientResponse -> {
//Error Handling
}).bodyToMono(Response.class);
}
A body from ClientResponse should be extracted in a reactive way (javadoc) and lambda in onStatus method should return another Mono (javadoc). To sum up, take a look at below example
onStatus(HttpStatus::isError, response -> response
.bodyToMono(Map.class)
.flatMap(body -> {
var message = body.toString(); // here you should probably use some JSON mapper
return Mono.error(new Exception(message));
})
);
I've defined a RouterFunction bean, with handler function returning a response with string body, which is a JSON. The builder however sets the content type to text/plain on passing a string to body
ServerResponse.ok().body(responseString).build() // Content type set to text/plain
#Bean
public RouterFunction<ServerResponse> infoRouter(MyHandler myHandler) {
return nest(
path("info"),
route().GET("definitions", __ -> myHandler.getDefinitions()).build()
).filter(HandlerFilterFunction.ofResponseProcessor((serverRequest, serverResponse) ->
// TODO: Set content type header to application/json
));
}
I tried to clone the response using ServerResponse::from but it doesn't include the response body. Is there another way to do this?
I have some controller method like
#PostMapping("/*")
fun proxy(#RequestBody body: String): Mono<ByteArray> {
return roundRobinBean.getNext()
.post()
.uri("/api")
.body(BodyInserters.fromObject(body))
.retrieve()
.bodyToMono<ByteArray>()
.doOnSuccess{
threadPool.submit(PutToCacheJob(body, it, cacheBean))
}
.doOnError{
logger.error(it.message, it)
}
}
roundRobinBean return WebClient for some host. If i get connection timeout exception or get 500 response i need call another host or return data from cache. Have mono some handler for changing inner data?
You can use onErrorResume operator which lets you define a fallback in case of errors.