Recently, one of my spring boot applications was running into a severe internal server error. To make it even worse, it was not possible to just log the RequestBody in my RestController because spring boot was not even able to deserialize the JSON payload!
Unfortunately, spring boots tracing filter does not allow to log the body of HTTP requests. Furthermore, the tracing filter will log ALL requests, which is not what I wanted. My solution is a custom logging filter which will write the body of the request in case of an internal server error to the standard logger.
Additionally, it will only print the request body in case of an error, which will keep the log clean most of the time. It is also worth noting that you cannot just naively read the body of a request. Instead, it is necessary to wrap the body and copy the content of the stream while reading. Therefore, it is only possible to access the body content AFTER the actual processing of the request was done. Kudos Christian! Thank you very much for posting this article.
This is the best and the only solution that worked for me. Keep it up!! Works like charm!! I customized above mentioned code to log both request and response body for each request. Hi, I was trying to read the request body before submitting.
How to achieve this kind of requirement. Appreciate your help on the same. I allowed my self to copy paste it. Needed only one small change: line ErrorAttributes; import org.
Your email address will not be published. Save my name, email, and website in this browser for the next time I comment.
By using this form you agree with the storage and handling of your data by this website. IOException ; import java. UnsupportedEncodingException ; import java. Principal ; import java. LinkedHashMap ; import java. Map ; import javax. FilterChain ; import javax. ServletException ; import javax. HttpServletRequest ; import javax.To use WebClient, you need to include the spring-webflux module in your project.
If you have an existing Spring Boot project, you can add the spring-webflux module by adding the following dependency in the pom. You can read on and understand the bits and pieces of WebClient from scratch or download the entire demo project with all the examples from Github.
WebClient also comes with a builder that gives you a bunch of customization options including filters, default headers, cookies, client-connectors etc.
The retrieve method is the simplest way to get the response body. However, If you want to have more control over the response, then you can use the exchange method which has access to the entire ClientResponse including all the headers and the body.
You can use parameters in the request URI and pass their values separately in the uri function. All the parameters are surrounded by curly braces. The parameters will automatically be replaced by WebClient before making the request.
Finally, you can use various factory methods provided by BodyInserters class to construct a BodyInserter object and pass it in the body method.
WebClient supports request filtering using an ExchangeFilterFunction. You can use filter functions to intercept and modify the request in any way.
Spring WebClient – GET, PUT, POST, DELETE examples
For example, you can use a filter function to add an Authorization header to every request, or to log the details of every request. It can modify the ClientRequest and call the next ExchangeFilterFucntion in the filter chain to proceed to the next filter or return the modified ClientRequest directly to block the filter chain.
In all the examples above, we are including an Authorization header for basic authentication with the Github API. Since this is something that is common to all the requests, you can add this logic in a filter function while creating the WebClient. You can use it like this. The filter function will intercept every WebClient request and add this header. ExchangeFilterFunction API provides two factory methods named ofRequestProcessor and ofResponseProcessor for creating filter functions that intercepts the request and response respectively.
The logRequest filter function that we created in the previous section can be created using ofRequestProcessor factory method like this. If you want to intercept the WebClient response, you can use the ofResponseProcessor method to create a filter function like this.
The retrieve method in WebClient throws a WebClientResponseException whenever a response with status code 4xx or 5xx is received. Note that Unlike retrieve method, the exchange method does not throw exceptions in case of 4xx or 5xx responses. You need to check the status codes yourself and handle them in the way you want to.
You can use an ExceptionHandler inside your controller to handle WebClientResponseException and return an appropriate response to the clients like this. WebTestClient contains request methods that are similar to WebClient. In addition, it contains methods to check the response status, header and body.
You can download the complete sample project with all the examples from my github repository. Thanks for reading. I really enjoyed writing this article for you and I hope to see you soon in my next article. Liked the Article?Spring Framework 5 introduces WebClient, a component in the new Web Reactive framework that helps build reactive and non-blocking web applications. If you are new to reactive programming, checkout my course, Spring Framework 5: Beginner to Guru which covers reactive programming with Spring Framework 5.
But others can be plugged in through a custom ClientHttpConnector. You can create a WebClient using one of the static factory methods create or the overloaded create String. Another approach is to obtain a builder to create and configure an instance.
It continuously emits streams of data wrapped in a Flux. We will access the producer from a second service using WebClient. The service layer produces a stream of MovieEvent with a delay of 1 second continuously.
The Producer is a Maven project that you can download from the link provided at the end of this post. You need to clone it, import it to your IDE, and run. I have imported the producer as a Maven Project to IntelliJ and got it running on an embedded Netty server, as shown in this Figure.
The consumer communicates with two services:. Our second domain model is MovieEvent that models an event to be received from the Producer. The code of the MovieClientServiceImplementation class is this. Note that Line 32 calls the exchange method instead of retrieve to receive the response. The exchange method returns a Mono that represents the response body along with other information, such as status and headers. On the other hand, the retrieve method we used earlier is a lightweight way to access the response body directly.
The REST controller of the Consumer application define endpoints for clients to query for movies and subscribe to events. The MovieController class is this. WebTestClient is a thin shell around WebClient.
You can use it to perform requests and verify responses. One common question is whether WebClient is replacing the traditional RestTemplate, n ot at this time. RestTemplate will continue to exist within the Spring Framework for the foreseeable future.
This means, a call done using RestTemplate needs to wait till the response comes back to proceed further. On the other hand, as WebClient is asynchronous, the rest call need not wait till response comes back. Instead when there is a response, a notification will be provided. Like all of my tutorials, the source code for this post is available on GitHub here.
Hello, thx for the post, very useful!!!. I have a doubt. WebClient is thread safe? Because i supose that is thread safe by the documentation say that but i am not sure because several thread can set the uri at the same time webTestClient. Excellent article. Please reply. Your email address will not be published.Comment 2. Spring Boot 2. Since the release, I have been seeing more and more mentions of Spring WebFlux along with tutorials on how to use it.
But after reading through them and trying to get it working myself, I found it a bit hard to make the jump from the code included in the posts and tutorials I read to writing code that actually does something a tiny bit more interesting than returning a string from the back-end.
Before I continue, and after all this mentioning of WebFlux, what actually is it? It allows better vertical scaling without increasing your hardware resources. Being reactive, it now makes use of Reactive Streams to allow asynchronous processing of data returned from calls to the server.
This means we are going to see a lot less List s, Collection s, or even single objects. Instead, we'll see their reactive equivalents such as Flux and Mono from Reactor. Instead, let's get back to focusing on WebFlux.
Being that this tutorial is about WebFlux, including the spring-boot-starter-webflux is obviously a good idea. By using these dependencies together, our application can be fully reactive from front to back. At the same time, it does not replace it. Instead, it has been updated to allow reactive types to be used. This allows you to keep the same format that you are used to writing with Spring but with a few changes to the return types so Flux s or Mono s are returned instead.
Below is a very contrived example. For reference, reactive repositories will return a Flux for collections and a Mono for singular entities. The annotation method is not what I want to focus on in this post, though. But Spring WebFlux has our backs. It provides an alternative method to route and handle requests to our servers that lightly uses lambdas to write router functions. These are all the routes to methods in the PersonHandlerwhich we will look at later on. We have created a bean that will handle our routing.
The dark mode beta is finally here. Change your preferences any time. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. It prints as an object. Tried different castings and retrieving the body as a string using bodyToMono, toEntity but they return an object and not string exactly. Learn more. How to log spring webclient request and response body? Ask Question. Asked 5 months ago.
Active 5 months ago. Viewed times. It prints as an object Tried different castings and retrieving the body as a string using bodyToMono, toEntity but they return an object and not string exactly. Munni Munni 9 3 3 bronze badges. Active Oldest Votes. Sign up or log in Sign up using Google. Sign up using Facebook. Sign up using Email and Password. Post as a guest Name.
Email Required, but never shown. The Overflow Blog.Spring WebClient
Q2 Community Roadmap. The Unfriendly Robot: Automatically flagging unwelcoming comments. Featured on Meta.The WebClient is a non-blockingreactive HTTP client which has been introduced in Spring 5 and is included in the spring-webflux module. Following are characteristics of the WebClient:. We have just configured a base URI for requests performed through the client to avoid repeating the same host, port, base path, or even query parameters with every request. To exchange a request, we can use the exchange method as the following example:.
The method exchanges the request for a ClientResponse with full access to the response status and headers before extracting the body. Another way to exchange a request with the WebClient is to use the retrieve method:. The retrieve method is a variant of the exchange method that provides the shortest path to retrieving the full response i. M5 with spring-boot-starter-webflux. Then we optionally provide the body for the request and call the retrieve or exchange method:. Then we optionally provide the body for the request and call the retrieve method:.
Notice that in above example, firstly we create a Book without the Author in the first request to the server. After that, we update the author for the book in the second request.
In the above example, we create a book first. Then we delete the book and validate the response. Notice that Spring 5 already provides us a basic authentication filter which can be found in the ExchangeFilterFunctions class. We can see that the easiest way to exchange a request is to use the retrieve method while we have more control over the response body when we use the exchange method. The sample code presented in this tutorial is available on my Github project.
Using Netflix Feign with Spring Cloud. Basic Authentication with Open Feign. File Uploading with Open Feign.
Spring WebClient with Spring Webflux RestAPIs | SpringBoot 2
URL package. Shares HTTP codecs and other infrastructure with the server functional web framework. OK, response. OK, resEntity. OKresponse. OKresEntity.GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together. Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community. Already on GitHub? Sign in to your account.
Would be great if the request can be logged in a human readable way directly instead of using special tools. JRE: 1. Linux 4. It's not accurate to say the output is not human readable.
You can clearly see the text in the right-hand column. That said I agree there should be an intermediate level of logging, that doesn't show individual bytes, is easier to read, and more compact. The current output is very verbose and quickly fills up log files, so it should be left as the most detailed level. The simple e. JSON payload is enough most of the time. So I would love to have an option to simply switch. But when looking at multiple requests from the same HttpClientit feels like this gives too much information and that we should have an intermediate level.
Other people on StackOverflow are discussing this issue. Just to add on here as well. With WebClient it doesn't seem so trivial to get similar output maybe its there and I just don't know where it is - I'm no reactive expert by any means.
Are you interested in providing a PR with that functionality? For reactor-netty 0. They end with 0d 0a 0d 0a Skip to content. Dismiss Join GitHub today GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together. Sign up. New issue. Jump to bottom.
Milestone General Backlog. Copy link Quote reply. This comment has been minimized. Sign in to view. I'd like to turn this "question" issue into an enhancement request. What about the following: keep this detailed information at the TRACE level have a DEBUG level logging feature that writes less detailed information If we decide to go ahead with this, there are still a few questions to answer: how should we keep track of things in case of concurrent requests?
Concurrent requests: I think this is an important but irrelevant concern. The existing logs don't do anything special to track concurrent requests, and Sleuth or Zipkin exist to address that concern. Formatting payloads: Again, this seems to be outside the concern of the logging system. Are there any plans for this enhancement to be implemented? C 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 31 ontent-Length: 1 35 32 37 0d 0a 0d 0a Sign up for free to join this conversation on GitHub.
Already have an account?