Spring WebClient is a non-blocking, reactive HTTP client library introduced in Spring WebFlux, which is part of the Spring Framework. It provides a convenient way to make HTTP requests and consume RESTful APIs in a reactive and asynchronous manner. WebTestClient, on the other hand, is a testing utility provided by Spring Framework to test WebClient-based applications.
In this tutorial, we’ll cover the following topics:
- Setting up a Spring Boot project with WebClient
- Making GET, POST, PUT, and DELETE requests with WebClient
- Handling response data and errors with WebClient
- Testing WebClient-based applications using WebTestClient
Let’s get started!
1. Setting up a Spring Boot project with WebClient
To begin, make sure you have a Java Development Kit (JDK) installed on your machine. You’ll also need an IDE such as IntelliJ IDEA or Eclipse.
- Create a new Spring Boot project using the Spring Initializr (https://start.spring.io) or your preferred IDE.
- Include the following dependencies in your project’s
pom.xml
(for Maven) orbuild.gradle
(for Gradle):
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
- Set up a simple Spring Boot application class with an
@SpringBootApplication
annotation:
1
2
3
4
5
6
7
8
9
10
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WebClientDemoApplication {
public static void main(String[] args) {
SpringApplication.run(WebClientDemoApplication.class, args);
}
}
- Create a service or controller class where you’ll use WebClient to make HTTP requests. For demonstration purposes, let’s create a
UserService
class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
@Service
public class UserService {
private final WebClient webClient;
public UserService() {
this.webClient = WebClient.create();
}
// Implement your methods to make HTTP requests using WebClient
// ...
}
With the initial setup complete, we can move on to making HTTP requests with WebClient.
2. Making GET, POST, PUT, and DELETE requests with WebClient
WebClient provides methods for various HTTP request types. Let’s see how to use them.
GET Request
To make a GET request with WebClient, use the get()
method and provide the request URL. You can then retrieve the response using the retrieve()
method.
1
2
3
4
5
6
7
8
9
10
11
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
// ...
ResponseSpec response = webClient.get()
.uri("https://api.example.com/users")
.retrieve();
String responseBody = response.bodyToMono(String.class).block();
System.out.println(responseBody);
POST Request
To make a POST request, use the post()
method and provide the request URL. You can then send the request body using the body()
method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
// ...
ResponseSpec response = webClient.post()
.uri("https://api.example.com/users")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(userJson)
.retrieve();
String responseBody = response.bodyToMono(String.class).block();
System.out.println(responseBody);
PUT Request
To make a PUT request, use the put()
method and provide the request URL. You can send the request body using the body()
method, similar to the POST request.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
// ...
ResponseSpec response = webClient.put()
.uri("https://api.example.com/users/{id}", userId)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(updatedUserJson)
.retrieve();
String responseBody = response.bodyToMono(String.class).block();
System.out.println(responseBody);
DELETE Request
To make a DELETE request, use the delete()
method and provide the request URL.
1
2
3
4
5
6
7
8
9
10
11
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
// ...
ResponseSpec response = webClient.delete()
.uri("https://api.example.com/users/{id}", userId)
.retrieve();
String responseBody = response.bodyToMono(String.class).block();
System.out.println(responseBody);
3. Handling response data and errors with WebClient
WebClient provides various methods to handle response data and errors. Here are a few examples:
Handling JSON response
If the response from the server is in JSON format, you can deserialize it into a Java object using the bodyToMono()
method.
1
2
3
4
5
6
7
8
9
10
11
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
// ...
ResponseSpec response = webClient.get()
.uri("https://api.example.com/users/{id}", userId)
.retrieve();
User user = response.bodyToMono(User.class).block();
System.out.println(user.getName());
Handling error responses
You can use the onStatus()
method to handle specific HTTP status codes and errors returned by the server.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
import org.springframework.web.reactive.function.client.WebClientException;
// ...
ResponseSpec response = webClient.get()
.uri("https://api.example.com/users/{id}", userId)
.retrieve();
response.onStatus(HttpStatus.NOT_FOUND, clientResponse -> {
throw new WebClientException("User not found");
});
User user = response.bodyToMono(User.class).block();
System.out.println(user.getName());
4. Testing WebClient-based applications using WebTestClient
Spring Framework provides WebTestClient to test WebClient-based applications. You can use it to mock HTTP responses and verify request parameters.
To use WebTestClient, follow these steps:
- Add the following dependency to your project’s test scope in the
pom.xml
(for Maven) orbuild.gradle
(for Gradle):
1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
- Create a test class and annotate it with
@RunWith(SpringRunner.class)
(for JUnit 4) or@ExtendWith(SpringExtension.class)
(for JUnit 5). Add the@SpringBootTest
annotation to load the Spring context.
1
2
3
4
5
6
7
8
9
10
11
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@RunWith(SpringRunner.class)
@SpringBootTest
public class WebClientTests {
// ...
}
- Create a
WebTestClient
instance and use it to perform HTTP requests and verify responses.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
@SpringBootTest
public class WebClientTests {
@Autowired
private WebTestClient webTestClient;
@Test
public void testGetUser() {
webTestClient.get()
.uri("/users/{id}", "123")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody(User.class)
.value(user -> assertEquals("John Doe", user.getName()));
}
// ...
}
In the example above, we use WebTestClient
to make a GET request to /users/123
and expect an HTTP status of 200 (OK). We also expect the response body to be deserialized into a User
object and verify its name.
That’s it! You’ve learned how to use Spring WebClient and WebTestClient to make HTTP requests, handle responses, and test WebClient-based applications.
Feel free to explore more features provided by WebClient and WebTestClient to suit your application’s needs.