Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve the final location of a given URL in Java

I am trying to retrieve the final location of a given URL (String ref) as follows:

        HttpURLConnection con = (HttpURLConnection)new URL(ref).openConnection();
        con.setInstanceFollowRedirects(true);
        con.setRequestProperty("User-Agent","");
        int responseCode = con.getResponseCode();
        return con.getURL().toString();

It works in most cases, but rarely returns a URL which yet contains another redirection.

What am I doing wrong here?

Why do I get responseCode = 3xx, even after calling setInstanceFollowRedirects(true)?

UPDATE:

OK, responseCode can sometimes be 3xx.

If it happens, then I will return con.getHeaderField("Location") instead.

The code now is:

        HttpURLConnection con = (HttpURLConnection)new URL(ref).openConnection();
        con.setInstanceFollowRedirects(true);
        con.setRequestProperty("User-Agent","");
        int responseType = con.getResponseCode()/100;
        while (responseType == 1)
        {
            Thread.sleep(10);
            responseType = con.getResponseCode()/100;
        }
        if (responseType == 3)
            return con.getHeaderField("Location");
        return con.getURL().toString();

Will appreciate comment should anyone see anything wrong with the code above.

UPDATE

  • Removed the handling of code 1xx, as according to most commenters it is not necessary.
  • Testing if the Location header exists before returning it, in order to handle code 304.

        HttpURLConnection con = (HttpURLConnection)new URL(ref).openConnection();
        con.setInstanceFollowRedirects(true);
        con.setRequestProperty("User-Agent","");
        if (con.getResponseCode()/100 == 3)
        {
            String target = con.getHeaderField("Location");
            if (target != null)
                return target;
        }
        return con.getURL().toString();
    
like image 764
barak manos Avatar asked Dec 27 '13 19:12

barak manos


1 Answers

HttpURLConnection will not follow redirects if the protocol changes, such as http to https or https to http. In that case, it will return the 3xx code and you should be able to get the Location header. You may need to open a connection again in case that new url also redirects. So basically, use a loop and break it when you get a non-redirect response code. Also, watch out for infinite redirect loops, you could set a limit for the number of iterations or check if each new url has been visited already.

like image 153
aditsu quit because SE is EVIL Avatar answered Sep 19 '22 18:09

aditsu quit because SE is EVIL