Клиент Jersey jax.rs 2.5 выполняет перенаправление с HTTP на HTTPS

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

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

Я нашел этот вопрос SO (Клиент Джерси не следует перенаправлениям), однако он предусмотрен для серии jersey 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

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

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


person devlearn    schedule 14.02.2014    source источник


Ответы (3)


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

webTarget.property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE);
person Nitin    schedule 14.08.2014
comment
вы уверены, что последний параметр неверен? Мне кажется, это просто отключает перенаправление :) - person devlearn; 19.08.2014
comment
Это должно быть webTarget.property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE), как отметил предыдущий комментатор. - person Laird Nelson; 29.06.2016
comment
Это работает только для Джерси; ClientProperties - это класс Джерси. JAX-RS пока не определяет никаких параметров обработки перенаправления. - person rü-; 27.10.2017
comment
Это не правильно; это будет разрешать перенаправления только в том случае, если протокол не изменяется, но не перенаправляет HTTP- ›HTTPS. Кроме того, этот параметр в любом случае уже установлен по умолчанию. - person sleske; 26.09.2019
comment
-1, потому что это только трикотаж, но исходный автор явно попросил JAX-RS (который является стандартом, реализованным в трикотажной ткани, которую он в настоящее время использует). - person Ben; 13.01.2020

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

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());
   }
}
person devlearn    schedule 14.02.2014
comment
Я нашел здесь ответ stackoverflow.com/questions/1884230/: перенаправление с http на https не работает по соображениям безопасности. - person Maxim Mazin; 12.01.2017
comment
не забудьте а) пометить фильтр @javax.ws.rs.ext.Provider и б) register на клиенте. - person Frank Neblung; 25.02.2019
comment
@FrankNeblung: в зависимости от того, как он зарегистрирован, аннотация может не требоваться. Но его обязательно нужно зарегистрировать в JAX-RS. - person sleske; 27.09.2019
comment
Хотя это действительно работает в том смысле, что оно успешно следует за перенаправлением, у него есть некоторые проблемы. Когда я попытался использовать его, Content-Type, возвращенный response.getMediaType (), был Content-Type, возвращенным первым запросом, а не перенаправленным запросом. Таким образом, кажется, что повторное использование ResponseContext таким образом не является чистым решением. - person sleske; 27.09.2019

Это происходит потому, что 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);
person Maxim Mazin    schedule 12.01.2017