Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey is not following 302 redirects

Tags:

java

rest

jersey

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

like image 307
Razor Storm Avatar asked Apr 29 '15 22:04

Razor Storm


1 Answers

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

    }

}
like image 60
stringy05 Avatar answered Nov 14 '22 02:11

stringy05