10

I have a url which redirects to another url.I want to be able to get the final redirected URL.My code:

    public class testURLConnection
    {
    public static void main(String[] args) throws MalformedURLException, IOException {

    HttpURLConnection con =(HttpURLConnection) new URL( "http://tinyurl.com/KindleWireless" ).openConnection();

    System.out.println( "orignal url: " + con.getURL() );
    con.connect();

System.out.println( "connected url: " + con.getURL() );
InputStream is = con.getInputStream();
System.out.println( "redirected url: " + con.getURL() );
is.close();

} }

It always gives original url whereas the redirectURL is:http://www.amazon.com/Kindle-Wireless-Reading-Display-Globally/dp/B003FSUDM4/ref=amb_link_353259562_2?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-10&pf_rd_r=11EYKTN682A79T370AM3&pf_rd_t=201&pf_rd_p=1270985982&pf_rd_i=B002Y27P3M.

How can i get this final redirected URL.

Here is what i tried with looping till we get redirects.Still doesent fetch the desired url:

    public static String fetchRedirectURL(String url) throws IOException
    {
HttpURLConnection con =(HttpURLConnection) new URL( url ).openConnection();
//System.out.println( "orignal url: " + con.getURL() );
con.setInstanceFollowRedirects(false);
con.connect();


InputStream is = con.getInputStream();
if(con.getResponseCode()==301)
    return con.getHeaderField("Location");
else return null;
    }
    public static void main(String[] args) throws MalformedURLException, IOException {
String url="http://tinyurl.com/KindleWireless";
String fetchedUrl=fetchRedirectURL(url);
System.out.println("FetchedURL is:"+fetchedUrl);
while(fetchedUrl!=null)
{   url=fetchedUrl;
System.out.println("The url is:"+url);
    fetchedUrl=fetchRedirectURL(url);


}
System.out.println(url);

    }
Jeets
  • 3,189
  • 8
  • 34
  • 50
  • @SJuan76 Suprise Surprise - I am not getting the same behavior on My Machine - MACOSX .. I am getting the re-directed value................. orignal url: http://tinyurl.com/KindleWireless connected url: http://tinyurl.com/KindleWireless redirected url: http://www.amazon.com/Kindle-Keyboard-Free-Wi-Fi-Display/dp/B004HZYA6E – user1428716 Feb 19 '13 at 07:23
  • but the redirect url we get is not the final url.Final url is what i pasted.If you paste the tinyUrl in browser you then final url you get is :http://www.amazon.com/Kindle-Wireless-Reading-Display-Globally/dp/B003FSUDM4/ref=amb_link_353259562_2?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-10&pf_rd_r=11EYKTN682A79T370AM3&pf_rd_t=201&pf_rd_p=1270985982&pf_rd_i=B002Y27P3M – Jeets Feb 19 '13 at 07:54
  • @Jeets have u get answer of your question.because i am facing same issue.. – dipali Oct 28 '15 at 07:15

7 Answers7

21

Try this, I using recursively to using for many redirection URL.

public static String getFinalURL(String url) throws IOException {
    HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
    con.setInstanceFollowRedirects(false);
    con.connect();
    con.getInputStream();

    if (con.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM || con.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP) {
        String redirectUrl = con.getHeaderField("Location");
        return getFinalURL(redirectUrl);
    }
    return url;
}

and using:

public static void main(String[] args) throws MalformedURLException, IOException {
    String fetchedUrl = getFinalURL("<your_url_here>");
    System.out.println("FetchedURL is:" + fetchedUrl);

}
duyhungws
  • 321
  • 4
  • 9
  • 1
    Thank you. setInstanceFollowRedirects() is what I needed. – AJC Dec 12 '19 at 20:11
  • Great solution. But why the getHeaderField("Location")? Thanks – Amg91 May 21 '20 at 18:51
  • This can be more general. As it is, it doesn't work in all cases, namely when the location field is not an absolute URL but a relative one. In that case, you should concatenate the base URL with the location header. – younes zeboudj Jun 10 '21 at 02:27
9
public static String getFinalRedirectedUrl(String url) {

    HttpURLConnection connection;
    String finalUrl = url;
    try {
        do {
            connection = (HttpURLConnection) new URL(finalUrl)
                    .openConnection();
            connection.setInstanceFollowRedirects(false);
            connection.setUseCaches(false);
            connection.setRequestMethod("GET");
            connection.connect();
            int responseCode = connection.getResponseCode();
            if (responseCode >= 300 && responseCode < 400) {
                String redirectedUrl = connection.getHeaderField("Location");
                if (null == redirectedUrl)
                    break;
                finalUrl = redirectedUrl;
                System.out.println("redirected url: " + finalUrl);
            } else
                break;
        } while (connection.getResponseCode() != HttpURLConnection.HTTP_OK);
        connection.disconnect();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return finalUrl;
}
ceph3us
  • 7,326
  • 3
  • 36
  • 43
aasha
  • 446
  • 4
  • 11
  • this code will in loop because in while loop you doesn't change connection object with new url, after first break add this line: `connection.disconnect(); connection = (HttpURLConnection) new URL(finalUrl).openConnection(); ` – Valix85 Oct 17 '18 at 08:34
2

My first idea would be setting instanceFollowRedirects to false, or using URLConnection instead.

In both cases, the redirect won't be executed, so you will receive a reply to your original request. Get the HTTP Status value and, if it is 3xx, get the new redirect value.

Of course there may be a chain of redirects, so probably you will want to iterate until you reach the real (status 2xx) page.

SJuan76
  • 24,532
  • 6
  • 47
  • 87
  • I tried this but still dosent give the correct url.I edited and added what I have tried as per your suggestion in the original post – Jeets Feb 19 '13 at 08:59
1

@user719950 On my MAC-OSX - this solves the issue of truncated HTTP URL :

To your original code , just add this below line : // You have to find through your browser what is the Request Header IE / Chrome is sending. I still dont have the explanation as why this simple setting is causing correct URL :)

HttpURLConnection con =(HttpURLConnection) new URL
( "http://tinyurl.com/KindleWireless" ).openConnection();
 con.setInstanceFollowRedirects(true);
 con.setDoOutput(true);
  System.out.println( "orignal url: " + con.getURL() );     
         **con.setRequestProperty("User-Agent",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) 
    AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2  
   Safari/536.26.17");**                  

           con.connect();
    System.out.println( "connected url: " + con.getURL() );
    Thread.currentThread().sleep(2000l);
    InputStream is = con.getInputStream();
    System.out.println( "redirected url: " + con.getURL() );

    is.close();
user1428716
  • 2,078
  • 2
  • 18
  • 37
1

This might help

public static void main(String[] args) throws MalformedURLException,
    IOException {

HttpURLConnection con = (HttpURLConnection) new URL(
        "http://tinyurl.com/KindleWireless").openConnection(proxy);
    System.out.println("orignal url: " + con.getURL());
    con.connect();
    con.setInstanceFollowRedirects(false);
    int responseCode = con.getResponseCode();
    if ((responseCode / 100) == 3) {
        String newLocationHeader = con.getHeaderField("Location");
        responseCode = con.getResponseCode();
        System.out.println("Redirected Location " + newLocationHeader);
        System.out.println(responseCode);
    }

}
Community
  • 1
  • 1
Manish Singh
  • 3,463
  • 22
  • 21
0

@JEETS Your fetchRedirectURL function may not work because there are a variety of HTTP codes for redirects. Change it to a range check and it will work.

public static String fetchRedirectURL(String url) throws IOException
    {
HttpURLConnection con =(HttpURLConnection) new URL( url ).openConnection();
//System.out.println( "orignal url: " + con.getURL() );
con.setInstanceFollowRedirects(false);
con.connect();

InputStream is = con.getInputStream();
if(con.getResponseCode()>=300 && con.getResponseCode() <400)
    return con.getHeaderField("Location");
else return null;
    }
0

This one goes recursively in case there are multiple redirects:

protected String getDirectUrl(String link) {
    String resultUrl = link;
    HttpURLConnection connection = null;
    try {
        connection = (HttpURLConnection) new URL(link).openConnection();
        connection.setInstanceFollowRedirects(false);
        connection.connect();
        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_MOVED_TEMP) {
            String locationUrl = connection.getHeaderField("Location");

            if (locationUrl != null && locationUrl.trim().length() > 0) {
                IOUtils.close(connection);
                resultUrl = getDirectUrl(locationUrl);
            }
        }
    } catch (Exception e) {
        log("error getDirectUrl", e);
    } finally {
        IOUtils.close(connection);
    }
    return resultUrl;
}
Alécio Carvalho
  • 13,481
  • 5
  • 68
  • 74