How to set HTTP header in RESTEasy client framework?

45,040

Solution 1

I have found a solution:

import org.apache.commons.httpclient.HttpClient;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.client.ProxyFactory;
import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.spi.ResteasyProviderFactory;

RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
HttpClient httpClient = new HttpClient();
ApacheHttpClientExecutor executor = new ApacheHttpClientExecutor(httpClient) {
    @Override
    public ClientResponse execute(ClientRequest request) throws Exception {
        request.header("X-My-Header", "value");
        return super.execute(request);
    }           
};

SimpleClient client = ProxyFactory.create(SimpleClient.class, "http://localhost:8081", executor);
client.putBasic("hello world");

Solution 2

In your client proxy interface, use the @HeaderParam annotation:

public interface SimpleClient
{
   @PUT
   @Path("basic")
   @Consumes("text/plain")
   public void putBasic(@HeaderParam("Greeting") String greeting);
}

The call in your example above would add an HTTP header that looks like this:

Greeting: hello world

Solution 3

With RestEasy 3.x I use ClientRequestFilters. In the below example there is a continuous integration (CI) server listening for requests running in the background. The test and the CI server use the same database and entity classes.

Assume that a tenant named 'test-tenant' does in fact exist, and there is a user 'root' that belongs to that tenant, and the user has the password specified below.

private static final String BASE_URI = "http://localhost:" + PORT;
@Test(groups = "functionalTests")
public void testGetTenant() throws Exception {
    Client client = ClientBuilder.newClient();
    ResteasyWebTarget target = (ResteasyWebTarget)client.target(BASE_URI);
    client.register(new AddAuthHeadersRequestFilter("root", "DefaultPasswordsAre:-("));
    TenantResource resource = target.proxy(TenantResource.class);

    RestTenant restTenant = resource.getTenant(tenant.id().value().toString());

    assertThat(restTenant.getName(), is("test-tenant"));
    assertThat(restTenant.isActive(), is(true));
}

And the AddAuthHeadersRequestFilter class:

public static class AddAuthHeadersRequestFilter implements ClientRequestFilter {

    private final String username;
    private final String password;

    public AddAuthHeadersRequestFilter(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        String token = username + ":" + password;
        String base64Token = Base64.encodeBase64String(token.getBytes(StandardCharsets.UTF_8));
        requestContext.getHeaders().add("Authorization", "Basic " + base64Token);
    }
}

The import statements (assuming you just paste the test and the static class into a single TestNg test-class file):

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import org.testng.annotations.Test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import org.apache.commons.codec.binary.Base64;

Solution 4

Even easier:

    ResteasyClient client = new ResteasyClientBuilder().build();
    ResteasyWebTarget target = client.target("https://test.com");
    Response response = target.request().header("Authorization", "Basic test123")
            .acceptEncoding("gzip, deflate")
            .post(Entity.entity(some_xml, "application/x-www-form-urlencoded"));
Share:
45,040
Lukasz R.
Author by

Lukasz R.

Updated on July 09, 2022

Comments

  • Lukasz R.
    Lukasz R. almost 2 years

    RESTEasy (a JAX-RS implementation) has a nice client framework, eg:

    RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
    
    SimpleClient client = ProxyFactory.create(SimpleClient.class, "http://localhost:8081");
    client.putBasic("hello world");
    

    How do you set HTTP headers?

    Clarification:

    The solution proposed by jkeeler is a good approach, but I want to set HTTP headers on ProxyFactory level and I don't want to pass headers to the client object. Any ideas?

  • Lukasz R.
    Lukasz R. almost 13 years
    Thanks, this is good approach, but I'm looking for other solution. I've clarified the question.
  • Eric Bowman - abstracto -
    Eric Bowman - abstracto - over 12 years
    How does ProxyFactory know about your executor? Seems disturbingly "magic".
  • Lukasz R.
    Lukasz R. over 12 years
    @EricBowman - you have right, the code was not correct. I've fixed it. You have to pass the executor variable as a parameter to the ProxyFactory.create() method.
  • Fabio Ebner
    Fabio Ebner almost 7 years
    @jkeeler just what I looking for? have a easy way to put this param required in all my methods in this interface?? tks
  • josh-cain
    josh-cain over 5 years
    +1 for this approach - when a header is required (I.E. "Authorization"), it's so much cleaner to specify in the interface.
  • Adrian Escutia Soto
    Adrian Escutia Soto over 3 years
    This is a good answer, but even better: stackoverflow.com/a/34679686/5078874
  • jmizv
    jmizv almost 2 years
    Any reasons why this would not work with org.jboss.resteasy:resteasy-client:3.6.1.Final? It's such a simple solution but I need to use ggranum's solution to get headers added :/