Rest Jersey jax.rs客户端2.5遵循从HTTP到HTTPS的重定向

Rest Jersey jax.rs客户端2.5遵循从HTTP到HTTPS的重定向,rest,tomcat,redirect,jersey-2.0,jersey-client,Rest,Tomcat,Redirect,Jersey 2.0,Jersey Client,我有一个设置,托管我的REST服务器的tomcat服务器将调用从HTTP(端口9080)重定向到HTTPS(端口9443) 我正在使用jersey 2.5实现,无法将客户端配置为遵循重定向 我发现这个问题很严重(),但是它是为jersey 1.X系列提供的,并且API已经更改 我已尝试使用以下测试代码将其改编为2.5版本: SSLContextProvider ssl = new TrustAllSSLContextImpl(); // just trust all certs Respon

我有一个设置,托管我的REST服务器的tomcat服务器将调用从HTTP(端口9080)重定向到HTTPS(端口9443)

我正在使用jersey 2.5实现,无法将客户端配置为遵循重定向

我发现这个问题很严重(),但是它是为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
2014年2月14日12:23:45 PM org.glassfish.jersey.filter.loggingpilter log
信息:1*在主线程上发送客户端请求
1>获取http://testhost.domain.org:9080/rest.webapp/api/v1/hello/
2014年2月14日下午12:23:45 org.glassfish.jersey.filter.loggingpilter log
信息:1*在主线程上收到客户端响应
1 < 302
1<缓存控制:专用
1<内容长度:0
日期:2014年2月14日星期五11:38:59 GMT
有效期:周四,1970年1月1日01:00:00 CET
1<地点:https://testhost.domain.org:9443/rest.webapp/api/v1/hello/
1<服务器:Apache Coyote/1.1
从jersey文档中,我了解到需要做的只是将ClientProperties.FOLLOW_REDIRECTS属性添加到客户端,但情况显然不是这样。我还发现一些消息,表明可能需要客户端筛选器来跟踪重定向,但没有找到这方面的示例或指南


因此,如果任何有jax.rs和重定向经验的人都能给我指出一些方向/文档/示例代码,我将不胜感激。

我最终通过一个过滤器解决了这个问题,不确定这是否是最佳解决方案,敬请指教:

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

正确的方法是:

webTarget.property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE);
发生这种情况的原因是,如果URL方案在重定向过程中发生更改,Http(s)UrlConnection不会遵循重定向(请参见示例)。因此,可能的解决办法是

这看起来像

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

您确定最后一个参数为“false”吗?在我看来,这只是禁用重定向:)这应该是
webTarget.property(ClientProperties.FOLLOW\u REDIRECTS,Boolean.TRUE)
,正如前面的评论员所指出的。这只适用于Jersey;ClientProperties是一个Jersey类。JAX-RS没有指定任何重定向处理选项,是的,这是错误的;这将仅在协议未更改时启用重定向,而不是重定向HTTP->HTTPS。此外,默认情况下,此设置已经是“true”。-1因为这只是jersey,但原始作者明确要求提供JAX-RS(这是jersey目前使用的标准)。我在这里找到了一个答案:从http重定向到https出于安全原因不起作用。不要忘记a)使用
@javax.ws.rs.ext.Provider
注释过滤器,b)在客户端注册它。@FrankNeblung:根据注册方式,可能不需要注释。但是它肯定需要向JAX-RS注册。虽然这在成功遵循重定向的意义上是可行的,但它存在一些问题。当我尝试使用它时,response.getMediaType()返回的内容类型是第一个请求返回的内容类型,而不是重定向请求返回的内容类型。因此,像这样重复使用ResponseContext似乎不是一个干净的解决方案。