Search code examples
javarestgethttprequesthttpclient

How do I pass the Map key value pairs in HttpRequest header?


i want to send as many header key value as i want. which means i dont know how many header key value i would be passing beforehand. I think using .header() or .headers() wont work because to use this i need to know the number of header key value pair i would be putting when I'm writing the code itself and i can't make change unless i change the code itself.

for example : for the first time, i may just set "Content-Type" header. for the second time, i may want to set "Content-type" and "Authorization" header.

I have provided a simple sample code for your reference.

void func(Map<String,String> headerParams) {
         HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(someURL))
                .headers(headerParams)
                .method("GET",HttpRequest.BodyPublishers.noBody())
                .build();

         //some other code goes here

}

void func2(){
        Map<String,String> headerParams = new HashMap<>();
        //code that goes here will put necessary header key value pair by asking the user
        func(headerParams);

}

Solution

  • You can either flatten map or loop through map to build the header

    Suppose your Headers Map is

    Map<String, List<String>> headers = new HashMap<>();
    headers.put("header1", Arrays.asList("a", "b"));
    headers.put("header2", Arrays.asList("c"));
    headers.put("header3", Arrays.asList("d"));
    

    You can flatten the map to extract the headers from Map

    void funcX(Map<String, List<String>> headerParams) throws URISyntaxException {
        HttpRequest request = HttpRequest.newBuilder()
                             .uri(new URI("some url"))
                             .headers(flattenHeaders(headerParams))
                             .GET()
                             .build();
    }
    
    String[] flattenHeaders(Map<String, List<String>> headersMap) {
        return headersMap.entrySet().stream().flatMap(x ->
                x.getValue().stream().flatMap(y -> Stream.of(x.getKey(), y))).toArray(String[]::new);
    }
    

    Another way would be just loop through the map to build the header

    void funcY(Map<String, List<String>> headerParams) throws URISyntaxException {
      HttpRequest request = getBuilder(HttpRequest.newBuilder().uri(new URI("some url")), headerParams)
                            .GET()
                            .build();
            }
        
    HttpRequest.Builder getBuilder(HttpRequest.Builder builder, Map<String, List<String>> headerParams){
                    for (Map.Entry<String, List<String>> e : headerParams.entrySet()) {
                        for (String value : e.getValue()) {
                            builder.header(e.getKey(), value);
                        }
                    }
                    return builder;
                }
    

    Prefer the first one over the second approach.