restclientspring-boot-3java-21

How to add multiple headers to RestClient for Spring Boot 3.2


I am using org.springframework.http.HttpHeaders to hold on to my headers. I receive a request from a service, collect the headers from the request into the HttpHeaders, and then I want to make a new request using those same headers. I do not know what or how many headers there will be (there will be at least a couple custom ones that I add). I want to use the new RestClient for Spring Boot 3.2.

I know I can enter them with .header(key, value), but I do not know how many headers I will have. Can I use .headers(Consumer<HttpHeaders>)? And how would I use it? I have tried looping through my headers to add them, but when I try to send my request it will timeout.

return restClient.post()
    .uri(new URI(endpoint))
    .body(bodyStr)
    .headers(/*how?*/)
    .retrieve()
    .body(MyClass.class);

I have tried this:

return restClient.post()
    .uri(new URI(endpoint))
    .body(body)
    .headers(headers -> headers.addAll(httpHeaders))
    .retrieve()
    .body(MyClass.class);

But that will timeout.


Solution

  • You can utilize defaultHeaders(...) provided with RestClient while creating its bean. Below is the sample code snippet that you can use to create RestClient bean in your configuration class.

    RestClient.builder()
            .baseUrl("your_url_here")
            .defaultHeaders(
                httpHeaders -> {
                  httpHeaders.setBasicAuth("your_username", "your_password");
                  httpHeaders.set("Content-Type", "application/json");
                  httpHeaders.set("custom_header_1", "custom_value");
                  httpHeaders.set("custom_header_2", "custom_value");
                })
            .build();
    

    Besides, you can add as many headers you want. If you have dynamic headers, then you can construct the headers before making any REST call using MultiValueMap and supply it during your REST call. Below is the code snippet to support this:

    // You can create this multi value map using your preferred loop
    MultiValueMap<String, String> multiHeaders = new LinkedMultiValueMap<>();
        multiHeaders.add("Content-Type", "application/json");
        multiHeaders.add("Accept", "application/json");
        multiHeaders.add("Accept-Charset", "utf-8");
        var response =
            restClient  //Keeping in mind that you have the bean already defined like above
                .get()
                .uri("your_url_here")
                .header("Authorization", "Bearer <token>")
                .headers(
                    headers -> {
                      headers.addAll(multiHeaders);
                    })
                .retrieve()
                .body(String.class); 
    

    However, I'm not clear about the concern that you have which is timeout. You might be getting timeout when you are trying to make a POST call and not timing out constructing headers. That doesn't make sense to me. If you are getting timeout for your REST call, you can always change the default timeout which is set to 120 seconds.