6

I am connecting to a server which first goes to an auth login page and then redirects.

ClientConfig config = new DefaultClientConfig();
config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
Client client = Client.create(config);
client.setFollowRedirects(true);
WebResource service = client.resource(UriBuilder.fromUri(url).build());

String output = service.path(resource)
        .path(model)
        .path(id)
        .accept(MediaType.APPLICATION_JSON)
        .get(String.class);

This is throwing an exception:

Exception in thread "ThreadJob" com.sun.jersey.api.client.UniformInterfaceException: GET https://url returned a response status of 302 Found at com.sun.jersey.api.client.WebResource.handle(WebResource.java:688) at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:509)

Jersey version 1.19

Razor Storm
  • 12,167
  • 20
  • 88
  • 148
  • couple of options to try here http://stackoverflow.com/questions/21778393/jersey-jax-rs-client-2-5-follow-redirect – stringy05 Apr 29 '15 at 23:14
  • 1
    also which version of jersey are you using and which http connector? – stringy05 Apr 29 '15 at 23:20
  • I am using jersey 1.19. I'm not aware of what httpconnector. This piece of code is the entirety of my jersey code and I didn't import any httpconnector explicitly – Razor Storm Apr 29 '15 at 23:26

2 Answers2

10

I find that often Jersey sucks. You would almost think they meant you to do this sort of thing and they add the "followRedirect" options to simply confuse the user.

import static org.junit.Assert.*;

import java.util.logging.Logger;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;

import org.junit.Test;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.ClientFilter;
import com.sun.jersey.api.client.filter.LoggingFilter;


public class TestJerseyRedirect {

    @Test
    public void test() {
        ClientConfig config = new DefaultClientConfig();
        config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
        com.sun.jersey.api.client.Client client = Client.create(config);
        client.setFollowRedirects(true);

        LoggingFilter logging = new LoggingFilter(Logger.getAnonymousLogger());


        WebResource service = client.resource(UriBuilder.fromUri("http://mail.google.com").build());
        service.addFilter(logging);
        try {
            String output = service.path("mail")
                .accept(MediaType.TEXT_HTML)
                .get(String.class);

            System.out.println(output);

        } catch (UniformInterfaceException e) {

            if (e.getResponse().getStatus() == 302) {
                String location = e.getResponse().getHeaders().getFirst("Location");

                WebResource service2 = client.resource(UriBuilder.fromUri(location).build());
                service2.addFilter(logging);
                String output2 = service2
                        .accept(MediaType.TEXT_HTML)
                        .get(String.class);

                    System.out.println(output2);

            }
            else {
                e.printStackTrace();
                throw e;
            }
        }

    }
}

which will work but is clearly not the right way to do it. This is less worse, but could give you trouble when there are, among other things, multiple redirects and the like.

@Test
public void testGoodWay() throws Exception {
    ClientConfig config = new DefaultClientConfig();
    config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
    com.sun.jersey.api.client.Client client = Client.create(config);
    client.setFollowRedirects(true);

    LoggingFilter logging = new LoggingFilter(Logger.getAnonymousLogger());



    WebResource service = client.resource(UriBuilder.fromUri("http://mail.google.com").build());
    service.addFilter(logging);
    service.addFilter(new RedirectFilter());

    try {
        String output = service.path("mail")
            .accept(MediaType.TEXT_HTML)
            .get(String.class);

        System.out.println(output);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

class RedirectFilter extends ClientFilter {

    @Override
    public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
        ClientHandler ch = getNext();
        ClientResponse resp = ch.handle(cr);

        if (resp.getClientResponseStatus().getFamily() != Response.Status.Family.REDIRECTION) {
            return resp;
        }
        else {
            // try location
            String redirectTarget = resp.getHeaders().getFirst("Location");
            cr.setURI(UriBuilder.fromUri(redirectTarget).build());
            return ch.handle(cr);
        }

    }

}
stringy05
  • 6,511
  • 32
  • 38
  • Thank you very much! I just had to modify this slightly to make it work: I changed `if (resp.getStatusInfo().getFamily() != Response.Status.Family.REDIRECTION)` to `if (resp.getClientResponseStatus().getFamily() != Response.Status.Family.REDIRECTION)`. – L42 Sep 28 '17 at 11:41
0

Alter your conectorProvider for ApacheConnectorProvider() and properties FOLLOW_REDIRECTS for true. Example:

        ClientConfig clientConfig = new ClientConfig();
        clientConfig.connectorProvider(new ApacheConnectorProvider());
        client = ClientBuilder.newClient(clientConfig);
        Response response = client.target("YOUR_URL")
                .property(ClientProperties.FOLLOW_REDIRECTS, true)**
                .request() 
                .get();

Doc: https://jersey.java.net/documentation/latest/client.html#d0e4895