Как установить HTTP-заголовок в клиентской среде RESTEasy?

RESTEasy (реализация JAX-RS) имеет хороший клиентская структура, например:

RegisterBuiltin.register(ResteasyProviderFactory.getInstance());

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

Как вы устанавливаете заголовки HTTP?

Пояснение:

Решение, предложенное jkeeler, хороший подход, но я хочу установить заголовки HTTP на уровне ProxyFactory и не хочу передавать заголовки объекту клиента. Есть идеи?


person Lukasz R.    schedule 03.08.2011    source источник


Ответы (4)


В RestEasy 3.x я использую ClientRequestFilters. В приведенном ниже примере сервер непрерывной интеграции (CI) прослушивает запросы, выполняемые в фоновом режиме. Тест и сервер CI используют одну и ту же базу данных и классы сущностей.

Предположим, что клиент с именем «test-tenant» действительно существует, и есть пользователь «root», принадлежащий этому арендатору, и у пользователя есть пароль, указанный ниже.

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));
}

И класс AddAuthHeadersRequestFilter:

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);
    }
}

Операторы импорта (при условии, что вы просто вставляете тест и статический класс в один файл тестового класса TestNg):

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;
person ggranum    schedule 20.10.2013
comment
Это хороший ответ, но еще лучше: stackoverflow.com/a/34679686/5078874 - person Adrian Escutia Soto; 29.09.2020

В интерфейсе клиентского прокси используйте аннотацию @HeaderParam:

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

Вызов в приведенном выше примере добавит заголовок HTTP, который выглядит следующим образом:

Greeting: hello world
person jkeeler    schedule 03.08.2011
comment
Спасибо, это хороший подход, но я ищу другое решение. Я уточнил вопрос. - person Lukasz R.; 05.08.2011
comment
@jkeeler именно то, что я ищу? есть простой способ поместить этот параметр во все мои методы в этом интерфейсе ?? спасибо - person Fabio Ebner; 26.05.2017
comment
+1 за этот подход - когда требуется заголовок (авторизация IE), так гораздо чище указать в интерфейсе. - person josh-cain; 04.01.2019

Еще проще:

    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"));
person m1416    schedule 04.03.2015

Я нашел решение:

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");
person Lukasz R.    schedule 19.08.2011
comment
Как ProxyFactory узнает о вашем исполнителе? Кажется тревожно волшебным. - person Eric Bowman - abstracto -; 21.08.2011
comment
@EricBowman - вы правы, код неверный. Я исправил это. Вы должны передать переменную executor в качестве параметра методу ProxyFactory.create(). - person Lukasz R.; 05.09.2011