0

How can I add a custom header to all outbound org.apache.http.client.HttpClient requests from a dropwizard service? E.g., whenever there is an outbound http request from any class in my dropwizard service I want to add a header "X-Powered-By:foo" to it automatically.

morpheus
  • 18,676
  • 24
  • 96
  • 159

1 Answers1

3

I am assuming you want to add that to outgoing requests that you poke. So i'll add that first.

DW uses jersey (so I am assuming you are using a jersey client to do your pokes). The jersey client uses an apache client (or can use) to do the actual requests.

Jersey uses filters to do what you need it to do. In this case, since you want to add a header to all requests, you will need to use the ClientRequestFilter. Consider this example:

public class HeaderTest {

    public static void main(String[] args) {
        // create the client
        Client newClient = ClientBuilder.newClient().register(MyClientRequestFilter.class).register(MyClientRequestPrintingFilter.class);

        // make a request
        newClient.target("http://google.com").request().get();
    }

    @Priority(1)
    public static class MyClientRequestFilter implements ClientRequestFilter {

        @Override
        public void filter(ClientRequestContext requestContext) throws IOException {
            System.out.println("Added header");
            requestContext.getHeaders().add("X-Powered-By", "foo");
        }

    }

    @Priority(2)
    public static class MyClientRequestPrintingFilter implements ClientRequestFilter {

        @Override
        public void filter(ClientRequestContext requestContext) throws IOException {
            requestContext.getHeaders().forEach((x,y) -> System.out.println("headerKey:" + x + " HEadervalue:" + y));
        }

    }
}

The class "MyClientRequestFilter" is registered to every single request. This code will always be executed (e.g. add a header to each and every request).

The second filter simply prints all headers in the request. Running this code I get:

Added header
headerKey:X-Powered-By HEadervalue:[foo]

I believe this is what you need.

Alternatively (in case I misunderstood), you can add a header to each response your server is doing. And this would be the filter (note: ContainerResponseFilter) that will do the do:

public static class MyHeaderResponseFilter implements ContainerResponseFilter {

        @Override
        public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
                throws IOException {
            responseContext.getHeaders().add("X-Powered-By", "foo");
        }

    }

And the test:

artur@pandaadb:~/dev/eclipse/eclipse_jee$ curl -v "localhost:9085/api/test/asd"
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9085 (#0)
> GET /api/test/asd HTTP/1.1
> Host: localhost:9085
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Wed, 24 Aug 2016 09:21:19 GMT
< Content-Type: application/json
< X-Powered-By: foo
< Vary: Accept-Encoding
< Content-Length: 5
< 
* Connection #0 to host localhost left intact
Hello

I hope that helps!

Artur

pandaadb
  • 6,306
  • 2
  • 22
  • 41
  • thanks for your answer but I am using org.apache.http.client.HttpClient to make the web requests – morpheus Aug 24 '16 at 16:42
  • adding for reference http://stackoverflow.com/questions/18570206/how-do-jersey-client-and-apache-http-client-compare – morpheus Aug 24 '16 at 16:47