Send Multiple Headers with Spring WebClient
In modern microservices and cloud-native applications, sending metadata with HTTP requests is a common need. If you have worked with REST APIs, you’ve probably dealt with headers—pieces of information like Content-Type, Authorization, or custom values that help servers understand how to process your request. When using Spring WebClient, a modern tool for making HTTP calls in reactive applications, it’s important to know how to set these headers properly. This guide will walk through how to send multiple headers in a single request and define default headers globally.
1. Understanding WebClient and HTTP Headers
Spring WebClient, introduced in Spring 5 as part of Spring WebFlux, is a non-blocking, reactive HTTP client designed for high-throughput microservices and event-driven systems. It replaces the older RestTemplate in reactive applications and supports:
- Asynchronous, event-loop based processing
- Reactive types like
MonoandFlux - A fluent API for chaining requests
- Header and cookie management
- JSON, XML, and stream support
1.1 What Are HTTP Headers?
HTTP headers are metadata sent alongside requests or responses. They inform the server or client how to interpret the message body or control aspects like caching, authentication, or content negotiation. Common headers include:
Content-Type: Specifies the format of the payload (e.g.,application/json)Authorization: Sends credentials such as bearer tokensAccept: Tells the server what format is expected in the responseX-Custom-*: For trace IDs, versioning, or feature toggles
Sample Endpoint to Test
Let’s create a test endpoint that returns a list of books and logs the received headers. First, define a basic Book class to use in our request payload.
public class Book {
private String title;
private String author;
public Book() {
}
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
Here is a controller that handles POST requests, receives Book objects sent by WebClient, and logs all incoming headers.
@RestController
@RequestMapping("/api/books")
public class BookController {
private static final Logger logger = LoggerFactory.getLogger(BookController.class);
@PostMapping
public ResponseEntity<String> createBook(@RequestBody Book book, @RequestHeader Map<String, String> headers) {
logger.info("Received book: {} by {}", book.getTitle(), book.getAuthor());
logger.info("Received headers: {}", headers);
return ResponseEntity.ok("Book received successfully");
}
}
WebClient Configuration
We can either autowire a WebClient.Builder or configure a reusable bean.
@Configuration
public class WebClientConfig {
@Bean
public WebClient webClient() {
return WebClient.builder()
.baseUrl("http://localhost:8080")
.build();
}
}
2. Setting Multiple Headers in WebClient (Per Request)
To set multiple headers on a single request, we can use .header() multiple times or use .headers(Consumer<HttpHeaders>). Here’s a service that sends a Book with multiple headers set at once.
@Service
public class BookClientService {
@Autowired
private WebClient webClient;
public Mono<String> sendBookWithHeaders() {
Book book = new Book("Effective Java", "Joshua Bloch");
// Set multiple headers
return webClient.post()
.uri("/api/books")
.headers(httpHeaders -> {
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.set("X-Correlation-Id", "12345");
httpHeaders.set("X-Client", "WebClientApp");
httpHeaders.set("Authorization", "Bearer mock-token");
})
.bodyValue(book)
.retrieve()
.bodyToMono(String.class);
}
}
Testing the Setup via REST Controller
Add a simple REST controller to trigger the client.
@RestController
@RequestMapping("/client")
public class WebClientTestController {
@Autowired
private BookClientService bookClientService;
@GetMapping("/send-book")
public String triggerClient() {
return bookClientService.sendBookWithHeaders().block(); // blocking only for demo/testing
}
}
When you access http://localhost:8080/client/send-book, observe the logs in the console and you should see something like this:
com.jcg.example.BookController : Received book: Effective Java by Joshua Bloch
2025-05-06T13:27:49.350+01:00 INFO 41612 --- [webclient-multi-header-example]
[nio-8080-exec-2] com.jcg.example.BookController :
Received headers: {accept-encoding=gzip, user-agent=ReactorNetty/1.2.5,
host=localhost:8080, accept=*/*, content-type=application/json,
x-correlation-id=12345, x-client=WebClientApp, authorization=Bearer mock-token, content-length=50}
3. Setting Default Headers Globally
In many applications, certain HTTP headers need to be sent with every request, such as authorization tokens, API versioning, or environment metadata. Instead of repeating these headers in every WebClient call, Spring WebClient allows us to define default headers globally when building the client. This ensures consistency and reduces boilerplate across your codebase.
Here’s how to configure default headers globally when creating a WebClient instance:
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:8080")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader("X-App-Version", "1.0")
.defaultHeader("X-Env", "development")
.build();
Once configured, all requests using this webClient instance will automatically include these headers, unless they are overridden on a per-request basis using .header(...).
Header Precedence: Request-specific headers override any global default headers if both are set for the same key. Internally, WebClient uses HttpHeaders (a Spring abstraction) that supports case-insensitive keys and multiple values for headers like Accept or Cookie.
4. Conclusion
In this article, we walked through the practical use of Java Spring WebClient to send multiple HTTP headers. The article demonstrated how to configure headers globally, customize them per request, and verify them through a sample controller. These practices are particularly valuable in microservice architectures that rely on consistent metadata, authentication, and request tracing.
5. Download the Source Code
This article explored how to set headers using Java Spring WebClient, covering both default and per-request configurations.
You can download the full source code of this example here: java spring webclient set headers




