In Spring 5, Spring received a reactive web framework: Spring WebFlux. This is designed to co-exist with existing Spring Web MVC APIs, but with support for non-blocking themes. With WebFlux, you can build asynchronous web applications using reactive flows and functional APIs to better support concurrency and scaling.
As part of this, Spring 5 introduced the newweb client
API, replaces the existing oneRestTemplate
Client. To useweb client
You can make synchronous or asynchronous HTTP requests with a functional fluent API that directly integrates with your existing Spring setup and responsive WebFlux framework.
In this article, we'll first look at how you can start making simple GET and POST requests to an API.web client
now, and then discuss how to takeweb client
also for extended use in extensive production applications.
How to make a GET request withweb client
Let's start with a simple GET request to read content from a server or API.
To get started, you'll first need to add some dependencies to your project if you don't already have them. If you use Spring Boot, you can usespring-boot-starter-webflux, or alternatively you can installspring-webfluxeReator-NettyImmediately.
In springweb client
The API is intended to be used in addition to an existing asynchronous HTTP client library. In most cases it is Netty Reactor, but you can also use Jetty Reactive HttpClient or Apache HttpComponents or integrate others by creating a custom connector.
Once installed, you can send your first GET requestweb client
:
WebClient-Client=web client.cry();web client.response specificationresponse specification=Client.to receive() .uri("http://beispiel.com") .to remember();
A lot is happening here:
- we created a
web client
example - We define an order with the
web client
Instance, specifying the request method (GET) and URI - We finish the configuration of the request and get a
response specification
That's all it takes to submit a request, but it's important to note that no requests have been submitted at this time!As a reactive API, the request isn't actually sent until something tries to read it or waits for the response.
How do we do it?
Handling an HTTP response withweb client
After making a request, we usually want to read the contents of the response.
In the example above, we call.to remember()
get oneresponse specification
for an order. This is an asynchronous operation that doesn't block or wait for the request itself, which means the request is still pending on the next line, so we can't access the response details yet.
Before we can get any value out of this async operation, you need to understand it.FloweMonotypes of reactors.
Flow
ONEFlow
represents a flow of items. It is a sequence that will asynchronously output any number of items (0 or more) into the future before completing (either successfully or with an error).
In reactive programming, this is our bread and butter. ONEFlow
it's a stream that we can transform (giving us a new stream of transformed events), buffer into a list, reduce to a single value, concatenate with other streams, and merge or block to wait for a value.
Mono
A mono is a specific but very common type ofFlow
: oneFlow
which asynchronously returns 0 or 1 results before completing.
In practice, it is similar to that of JavaSupplementaryFuture
: Represents a single future value.
If you want more information about this, have a look.Spring's own docsthat further explain reactive types and their relationship to traditional Java types.
read the body
To read the response text, we need aMono
(that is, an asynchronous future value) to the response content. We then need to somehow unpack this to trigger the request and get the content from the response body itself once it's available.
There are several ways to unpack an async value. First, let's use the simplest traditional option, blocking to wait for the data to arrive:
String responseBody=response specification.body for mono(line.class).Quadra();
This gives us a string containing the raw text of the response. You can pass different classes here to automatically parse the content into a suitable format or use aFlow
here for a stream of response parts (from an event-driven API, for example), but we'll get to that in a moment.
Please note that we do not check the status here. if we use.to remember()
, the client will automatically check the status code for us and provide a reasonable default by throwing an error for any 4xx or 5xx response. We'll also talk about custom status checks and error handling later.
How to send a complex POST request withweb client
We've seen how to send a very basic GET request, but what if we want to send something more advanced?
Let's look at a more complex example:
MultiValueMap<line,line>body values= Neubound MultiValueMap<>();body values.Add("Key", "Wert");body values.Add("another key", "other value");string response=Client.Post() .uri(NeuURI("https://httpbin.org/post")) .Header("To allow", "Inhaber MY_SECRET_TOKEN") .content type(media type.APPLICATION_FORM_URLENCODED) .to accept(media type.APPLICATION_JSON) .body(body inserter.fromFormData(body values)) .to remember() .body for mono(line.class) .Quadra();
as we can see hereweb client
allows us to configure headers using dedicated methods for common cases (.contentType(Type)
) or generic keys and values (.header(chave, valor)
).
In general it is preferable to use dedicated methods as their tighter typing helps us to provide the correct values and they include runtime validation to catch various invalid settings as well.
This example also shows how to add a body. Here are some options:
- we can call
.Body()
commonbody inserter
, which creates text content for nodes from form values, multipart values, data buffers, or other codeable types. - we can call
.Body()
commonFlow
(including aMono
) that can asynchronously stream content to build the request body. - we can call
.bodyValue(valor)
to supply a string or other directly encoded value.
Each of them has different use cases. Most developers unfamiliar with reactive flows won't find the Flux API useful at first, but as you invest more in the reactive ecosystem, asynchronous streams of streamed data like this will feel more natural.
How to take the springweb client
in production
The above should be enough to get you started asking basic queries and reading the answers, but there are a few more topics we need to cover if you want to build advanced applications around them.
Read response headers
So far, we've focused on reading the response body and ignoring the headers. Most of the time that's fine, and the important headers are handled for us, but you'll find that many APIs include valuable metadata in their response headers, not just the body.
These data are easily available on theweb client
API also with the.toEntity()
API that gives us aresponse entity, wrapped in aMono
.
This allows us to examine the response headers:
response entity<line>reply=Client.to receive() // ... .to remember() .to entity(line.class) .Quadra();HttpHeaders responseHeaders=reply.getHeader();List<line>HeaderWert=ResponseHeader.to receive("header-name");
Analyzing response bodies
In the examples above, we treat responses as simple strings, but Spring can also automatically decompose them into many supertypes for you by simply specifying a more specific type when reading the response, like this:
Mono<Person>reply=Client.Post() // ... .to remember() .body for mono(Person.class)
Which classes can be converted depends on theHttpMessageReader
that are present. By default, supported formats include:
- Conversion of each answer to
line
,Byte[]
,ByteBuffer
,data buffer
orResource
- Conversion of
application/x-www-form-urlencoded
answers insideMultiValueMap<String,String>>
- Conversion of
multipart/form-data
answers insideMultiValueMap<string, part>
- Deserializing JSON data using Jackson, if available
- Deserialization of XML data using Jackson's XML extension or JAXB, if available
This can also use the patternHttpMessageConverter
Configuration registered in your Spring application, allowing the message converters to be shared between the code of your WebMVC or WebFlux server and yoursweb client
instances. If you use Spring Boot, you can usethe preconfigured WebClient.Builder instanceto set this up automatically.
For more details have a look atSpring WebFlux-Codec-Documentation.
Manually manage response status
by default.to remember()
will check the error status for you. This is fine for simple cases, but you'll likely encounter many REST APIs that encode more detailed success information into their status codes (e.g., returning 201 or 202 values) or APIs where you want custom handling to add some bug status .
You can read the status ofresponse entity
, as we did for headers, but this is only useful for accepted statuses, because in that case error statuses throw an error before we get the entity.
To handle these states ourselves, we need to add aonStatus
handlers. This handler can match certain statuses and return amono<play>
(to track the specific error) ormonkey.read()
to prevent this status from being treated as an error.
It works like this:
Response Entity Response=Client.to receive() // ... .to remember() // Don't treat 401 responses as errors: .onStatus(Status->Status.Wert() ==401,customer response->Mono.File() ) .to entity(line.class) .Quadra();// Check and handle relevant status codes manually:What if (reply.getStatusCodeValue() ==401) { // ...} anders { // ...}
Make fully asynchronous requests
So far we called.Quadra()
block the thread completely for each response to wait for the response to arrive.
Within a traditional tightly threaded architecture, this might naturally fit in, but in a non-blocking design, we should avoid these types of blocking operations whenever possible.
Alternatively, we can handle requests by weaving transformations around ourMono
orFlow
Values to process and match values as they are returned and then pass themFlow
-Wrap the values in other non-blocking APIs, all fully asynchronous.
This is not the space to fully explain this paradigm or WebFlux from the beginning, but an exampleweb client
it can look like this:
@GetMapping("/User ID}")PrivateMono<from the user> getUserById(@PathVariableString-ID) { // Loads some user data asynchronously, for example from a database:Mono<BaseUserInfo>user information=getBaseUserInfo(I could); // Load user data with separate API WebClient:Mono<user signature>User Signature=Client.to receive() .uri("http://subscription-service/api/user/" +I could) .to remember() .body for mono(user signature.class); // Combine the monos: when both are ready, take these // Data from each and combine them into a user object.Mono<from the user>from the user=user information.zipMit(User Signature) .Map((tupel) -> Neufrom the user(tupel.getT1(),tupel.getT2()); // The mono resulting from the combined data can be returned immediately, // without waiting or blocking, and WebFlux sends // the response later, when all the data is ready: Returnsfrom the user;}
Testing with SpringWebTestClient
In addition toweb client
, Spring 5 includesWebTestClient
, which offers an interface very similar to theweb client
, but designed for convenient testing of server terminals.
We can configure this by creating aWebTestClient
linked to a server and sending actual requests over HTTP, or one linked to a singleRules
,RouterFunktion
orWebHandlerName
to run integration tests with simulated request and response objects.
It looks like this:
// Connect to a real server via HTTP:WebTestClient-Client=WebTestClient.bindToServer() .baseUrl("http://localhost:8000") .build up();// Or connect to a single WebHandler using dummy objects:WebTestClient-Client=WebTestClient.bindToWebHandler(handler) .build up();
After creating a WebTestClient, we can define requests like any otherweb client
.
To send the request and check the result, we call.Exchange()
and then use the assertion methods available there:
Client.to receive() .uri("/api/user/123") .Exchange() .expected state().was not found(); // Confirm this is a 404 response
There are a variety of assertion methods for checking response status, headers, and body - seeo JavaDocfor the complete list.
After providing yourweb client
code, you need to be able to debug it. HTTP requests are often the focal point of complex interactions and can fail in a number of interesting ways. It's helpful to see the requests and responses your customer is working with to understand what your system is doing, and entering your own data or bugs can be a powerful technique for manual testing.
For that you can useHTTP Toolkit, an open source, cross-platform tool that can capture traffic from a variety of Java HTTP clients and that includes special integration to automatically intercept Springweb client
.
After installing the HTTP toolkit, the next step is to intercept Java HTTP traffic. To do this, you can:
- In the HTTP Toolkit, click the Fresh Terminal button to open a terminal and launch your application from there; or
- Start your application normally and click the Attach to JVM button in the HTTP Toolkit to attach it to the already running JVM
After intercepting your traffic, you can inspect each request and response sent by your application from the HTTP Toolkit's Preview page:

You can also add mock page rules to interactively simulate HTTP responses or breakpoint requests or inject errors such as connection errors and timeouts.
Conclusion
In this article, we've seen everything you need to get started with Spring.web client
🇧🇷 WebFlux andweb client
they're mature and powerful APIs that still have a lot to offer beyond the classic Spring features, so try them out in your app today.
FAQs
How to send HTTP request in Spring Boot? ›
- Dependencies.
- GET Request.
- Get Response as Object.
- URL Parameters.
- Response Handing.
- Custom Request Headers.
- POST Request.
- PUT Request.
RestTemplate will still be used. But in some cases, the non-blocking approach uses much fewer system resources compared to the blocking one. So, WebClient is a preferable choice in those cases. All of the code snippets mentioned in the article can be found over on GitHub.
How do you pass query parameters in WebClient? ›To pass single-value query parameters, create a path of the base resource URI and then use the queryParam() method to append key-value pairs.
What are the 4 types of HTTP request methods? ›The most commonly used HTTP request methods are GET, POST, PUT, PATCH, and DELETE.
How do I give HTTP request? ›An HTTP client sends an HTTP request to a server in the form of a request message which includes following format: A Request-line. Zero or more header (General|Request|Entity) fields followed by CRLF. An empty line (i.e., a line with nothing preceding the CRLF) indicating the end of the header fields.
How do I send a post request using WebClient? ›- Create WebClient. ...
- Set the request URI if not set already.
- Set the request headers and authentication details, if any.
- Set the request body, if any.
- Call the retrieve() or exchange() method. ...
- Handle the response returned from the server.
WebClient provides a simple but limited wrapper around HttpWebRequest. And HttpClient is the new and improved way of doing HTTP requests and posts, having arrived with . NET Framework 4.5.
Can I send HTTP GET request with body from browser? ›So, yes, you can send a body with GET, and no, it is never useful to do so. This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress). Yes, you can send a request body with GET but it should not have any meaning.
Is WebClient multithreaded? ›Because WebClient is immutable it is thread-safe. WebClient is meant to be used in a reactive environment, where nothing is tied to a particular thread (this doesn't mean you cannot use in a traditional Servlet application).
Does WebClient use HttpClient? ›WebClient uses HttpClient indirectly, because HttpWebRequest uses HttpClient internally even in . NET Framework, since at least 2018.
Is WebClient immutable? ›
Once created, the WebClient is immutable which makes it thread safe. You can use webClient. mutate() to reconfigure it and get a new instance.
How to pass URL parameters in REST API? ›- Open the API Gateway console, and then choose your API.
- In the Resources pane, choose the configured HTTP method. ...
- In the Method Execution pane, choose Method Request.
- Expand the URL Query String Parameters dropdown list, then choose Add query string.
To add a parameter to the URL, add a /#/? to the end, followed by the parameter name, an equal sign (=), and the value of the parameter. You can add multiple parameters by including an ampersand (&) between each one.
How do I pass headers in WebClient? ›Set the body of the request to the given BodyInserter and perform the request. Set the body of the request to the given Publisher and perform the request. Add the given, single header value under the given name. Copy the given headers into the entity's headers map.
What are the 2 main HTTP request methods? ›The two most common HTTP methods are: GET and POST.
What are the 8 methods of HTTP? ›- GET Method. A GET request retrieves data from a web server by specifying parameters in the URL portion of the request. ...
- HEAD Method. ...
- POST Method. ...
- PUT Method. ...
- DELETE Method. ...
- CONNECT Method. ...
- OPTIONS Method. ...
- TRACE Method.
In particular, HTTP/2 is much faster and more efficient than HTTP/1.1.
How to send HTTP request from HTTPS? ›- Enter a URL in the field provided.
- Select either Use HTTP GET or Use HTTP POST. Enter HTTPS instead of HTTP in the URL to send the information using HTTPS.
- Enter the Body to POST.
- Starting with Orion Platform 2020.2, you can also specify the ContentType and Authentication: None.
- Create a URL object from the GET or POST URL String.
- Call the openConnection() method on the URL object that returns an instance of HttpURLConnection .
- Set the request method in HttpURLConnection instance (default value is GET ).
Find the URI of the external server or program. Add an HTTP verb. Include a header. Include an API key or access token.
How do I send a POST request to Rest API? ›
...
For both single and multiple RPC commands, HTTP Accept headers can be used to specify the return format using one of the following Content-Type values:
- application/xml (the default)
- application/json.
- text/plain.
- text/html.
To make a POST request to an API endpoint, you need to send an HTTP POST request to the server and specify a Content-Type request header that specifies the data media type in the body of the POST request. The Content-Length header indicates the size of the data in the body of the POST request.
How do I send a POST request? ›- POST HTML Form Example. POST /echo/post/form HTTP/1.1 Host: reqbin.com Content-Type: application/x-www-form-urlencoded Content-Length: 23 key1=value1&key2=value2.
- POST JSON Data Example. ...
- POST XML Data Example.
NET 6, the WebRequest, WebClient, and ServicePoint classes are deprecated. The classes are still available, but they're not recommended for new development. To reduce the number of analyzer warnings, only construction methods are decorated with the ObsoleteAttribute attribute.
Which is the best HttpClient for Java? ›Java version compatibility (current version of client) | Transparent content compression | |
---|---|---|
HttpURLConnection | 1.1+ (HTTP) 1.4+ (HTTPS) | No |
Java HttpClient | 9+ (as incubator module) 11+ (GA) | No |
Apache HTTPClient | 7+ | GZip Deflate |
OkHttp | 8+ | GZip Deflate Brotli |
If we do not want to add any external libraries, Java's native HTTPClient is the first choice for Java 11+ applications. Spring WebClient is the preferred choice for Spring Boot applications more importantly if we are using reactive APIs.
How do browsers send HTTP requests? ›The browser sends an HTTP request message to the server, asking it to send a copy of the website to the client (you go to the shop and order your goods). This message, and all other data sent between the client and the server, is sent across your internet connection using TCP/IP.
How do I send HTTP requests without a browser? ›Send an HTTP request by creating a URL and getting the connection for it, and casting it to HttpURLConnection. Add an "If-Modified-Since" header, with the download date of your local file. If the server responds with 304 (not modified), then your local version is up-to-date.
Can you send data with HTTP GET? ›Can I send data using the HTTP GET method? No, HTTP GET requests cannot have a message body. But you still can send data to the server using the URL parameters. In this case, you are limited to the maximum size of the URL, which is about 2000 characters (depends on the browser).
Is WebClient reactive? ›The Spring WebClient is a reactive HTTP library; it's the follow-up to the Spring RestTemplate which is now in maintenance mode. Also, whereas the RestTemplate was a synchronous blocking library, WebClient is an asynchronous non-blocking library.
What is the difference between WebClient and feign client? ›
Spring WebClient is a non-blocking reactive client to make HTTP requests. Feign is a library which helps us to create declarative REST clients easily with annotations and it provides better abstraction when we need to call an external service in Microservices Architecture.
How does WebClient handle error response? ›While Initialising WebClient
As mentioned in the code block, whenever a 5XX/4XX Error occurs, we can throw a user defined exception, and then execute error handling logic based on those user defined exceptions. Once this error Handler is defined, we can add it in the WebClient Initialisation.
The HttpClient is used to perform HTTP requests and it imported form @angular/common/http. The HttpClient is more modern and easy to use the alternative of HTTP. HttpClient is an improved replacement for Http. They expect to deprecate Http in Angular 5 and remove it in a later version.
What is the difference between HttpClient and HttpWebRequest? ›WebClient is just a wrapper around HttpWebRequest, so it uses HttpWebRequest internally. The WebClient bit slow compared to HttpWebRequest. But is very much less code. we can use WebClient for simple ways to connect and work with HTTP services.
What is the difference between WebClient and web server? ›In simple terms, the browsers you use on your computer or mobile devices are web clients. These are software designed to help end users access resources(web pages/files/services) on the internet. The computers or devices that store these resources are called Web Servers.
What is the difference between retrieve and exchange in WebClient? ›WebClient – retrieve() vs exchange()
exchange method provides more control and details like status, headers and response body, etc. retrieve() method provides automatic error signal (e.g. 4xx and 5xx). No automatic error signal is available for exchange() method and we need to check status code and handle it.
WebClient Dependency
In order to use WebClient in a Spring Boot Project we need add dependency on WebFlux library. Like any other Spring Boot dependencies, we have to add a starter dependency for WebFlux (spring-boot-starter-webflux).
To do so, you have to do the following steps : Add @Async annotation to the function you want to parallelize getCountriesByLanguage and getCountriesByRegion. Change the return type of the function by CompletableFuture<List<Country>>
How does HTTP request work in Spring Boot? ›- Makes the web server up.
- creates the war file , then host the war file on server.
- Then http requests are handled through servlet lying under spring-boot-starter-web.
To see both HTTP and HTTPS in action, create a simple REST controller. Build and deploy your Spring boot application. Once you application is up and running, try to open these URL's. You will get a reply from both URL's since we have enabled both HTTP and HTTPS in our Spring Boot application.
How do I get the HTTP request object in Spring Boot? ›
- @RequestHeader(value="Accept") String acceptHeader. @RequestHeader(value="Accept") String acceptHeader.
- import javax. servlet. http. ...
- Enumeration<String> hearderNames = request. getHeaderNames();
The two most common HTTP methods are: GET and POST.
Is HTTP request a REST API? ›REST APIs and HTTP APIs are both RESTful API products. REST APIs support more features than HTTP APIs, while HTTP APIs are designed with minimal features so that they can be offered at a lower price.
How do you communicate between HTTP and HTTPS? ›An HTTPS request is sent with a "code" which can be deciphered only by a properly configured HTTPS server. If anyone in between the sender and the recipient could open the request, they still could not understand it. Only the sender and the recipient, who know the "code," can decipher the message.
How do I connect to HTTP and HTTPS? ›The HTTP CONNECT method starts two-way communications with the requested resource. It can be used to open a tunnel. For example, the CONNECT method can be used to access websites that use SSL (HTTPS). The client asks an HTTP Proxy server to tunnel the TCP connection to the desired destination.
Can HTTP and HTTPS run on same port? ›This is not going to be possible with Apache. With Apache you cannot have HTTPS and HTTP running on the same port.
What is @request body in Spring Boot? ›Simply put, the @RequestBody annotation maps the HttpRequest body to a transfer or domain object, enabling automatic deserialization of the inbound HttpRequest body onto a Java object.
How do you log HTTP request and response in Spring Boot? ›Custom Request Logging
Among the Spring request interceptors, one of the noteworthy interfaces is HandlerInterceptor, which we can use to log the incoming request by implementing the following methods: preHandle() – we execute this method before the actual controller service method.
An HTTP request is made out of three components: request line, headers and message body.
How do I send HTTP request with username and password? ›We can do HTTP basic authentication URL with @ in password. We have to pass the credentials appended with the URL. The username and password must be added with the format − https://username:password@URL.
How do I use HTTP request in JSON? ›
- 2.1. Create a URL Object. ...
- 2.2. Open a Connection. ...
- 2.3. Set the Request Method. ...
- 2.4. Set the Request Content-Type Header Parameter. ...
- 2.5. Set Response Format Type. ...
- 2.6. Ensure the Connection Will Be Used to Send Content. ...
- 2.7. Create the Request Body. ...
- 2.8.
Use JSON to perform an HTTP request to retrieve data from a remote location. JSON is most commonly used in asynchronous HTTP requests. This is where an application pulls data from another application via an HTTP request on the web.