Джерси клиент jax.rs 2.5 следит за перенаправлением с HTTP на HTTPS

У меня есть настройка, где сервер tomcat, на котором размещаются мои серверы REST, перенаправляет вызовы из HTTP (порт 9080) на HTTPS (порт 9443).

Я использую реализацию jersey 2.5 и не могу настроить клиентов для перенаправления.

Я нашел этот вопрос SO (Джерси-клиент не следит за переадресацией), однако он предоставил трикотаж 1.X, и API изменился.

Я попытался адаптировать его для версии 2.5 со следующим тестовым кодом:

 SSLContextProvider ssl = new TrustAllSSLContextImpl(); // just trust all certs
 Response response  =     ClientBuilder.newBuilder()
     .sslContext(ssl.getContext()).newClient()
     .register(LoggingFilter.class)
     .target("http://testhost.domain.org:9080/rest.webapp/api/v1/hello/")
     .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE)
     .request().get();   
 Assertions.assertThat(response.getStatus()).isNotEqualTo(302);

Что не удается, поскольку клиент, похоже, не выполняет перенаправления. Вот что обеспечивает каротажный фильтр:

Feb 14, 2014 12:23:45 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Sending client request on thread main
1 > GET http://testhost.domain.org:9080/rest.webapp/api/v1/hello/

Feb 14, 2014 12:23:45 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Client response received on thread main
1 < 302
1 < Cache-Control: private
1 < Content-Length: 0
1 < Date: Fri, 14 Feb 2014 11:38:59 GMT
1 < Expires: Thu, 01 Jan 1970 01:00:00 CET
1 < Location: https://testhost.domain.org:9443/rest.webapp/api/v1/hello/
1 < Server: Apache-Coyote/1.1

Из документа jersey я понял, что все, что нужно сделать, это добавить к клиенту свойство ClientProperties.FOLLOW_REDIRECTS, но это, очевидно, не так. Я также нашел сообщения, указывающие, что, возможно, фильтр на стороне клиента необходимо следовать перенаправлениям, но не нашел примеров или рекомендаций по этому вопросу.

Итак, если кто-то, кто имеет опыт работы с jax.rs и перенаправлением, может указать мне на некоторые направления/документы/пример кода, я бы очень благодарен.

Ответ 1

правильный способ сделать это:

webTarget.property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE);

Ответ 2

Ну, я, наконец, понял это, используя фильтр, не уверен, что это лучшее решение, любые комментарии оценены:

public class FollowRedirectFilter implements ClientResponseFilter
{
   @Override
   public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException
   {
      if (responseContext.getStatusInfo().getFamily() != Response.Status.Family.REDIRECTION)
         return;

      Response resp = requestContext.getClient().target(responseContext.getLocation()).request().method(requestContext.getMethod());

      responseContext.setEntityStream((InputStream) resp.getEntity());
      responseContext.setStatusInfo(resp.getStatusInfo());
      responseContext.setStatus(resp.getStatus());
   }
}

Ответ 3

Это происходит потому, что Http (s) UrlConnection не следует перенаправлению, если схема URL изменяется во время перенаправления (см., Например, HTTPURLConnection Не следует перенаправлению с HTTP на HTTPS). Таким образом, возможное решение состоит в том, чтобы использовать альтернативный клиентский транспортный соединитель.

Это может выглядеть как

SSLContextProvider ssl = new TrustAllSSLContextImpl(); // just trust all certs

JerseyClientBuilder clientBuilder = new JerseyClientBuilder()
 .sslContext(ssl.getContext())
 .register(LoggingFilter.class);
clientBuilder.getConfiguration().connectorProvider(new org.glassfish.jersey.apache.connector.ApacheConnectorProvider());

JerseyClient client = clientBuilder.build();

Response response = client    
 .target("http://testhost.domain.org:9080/rest.webapp/api/v1/hello/")
 .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE)
 .request().get();
Assertions.assertThat(response.getStatus()).isNotEqualTo(302);