I have a setup where tomcat server hosting my REST servers redirects calls from HTTP (port 9080) to HTTPS ( port 9443 ).
I\'m using jersey 2.5 implementation and can
correct way to do this is:
webTarget.property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE);
Well I finally figured this out using a filter, not sure this is the best solution, any comments are appreciated :
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());
}
}
This happens because Http(s)UrlConnection doesn't follow redirect if URL scheme changes during the redirect (see e.g. HTTPURLConnection Doesn't Follow Redirect from HTTP to HTTPS ). So the possible solution is to use alternative client transport connector.
This could look like
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);