【问题标题】:java urlconnection get the final redirected URLjava urlconnection 获取最终重定向的 URL
【发布时间】:2013-02-03 19:00:57
【问题描述】:

我有一个重定向到另一个 url 的 url。我希望能够获得最终重定向的 URL。我的代码:

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

} }

它总是给出原始网址,而重定向网址是: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

我怎样才能得到这个最终重定向的 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);

    }

【问题讨论】:

标签: java


【解决方案1】:

试试这个,我使用递归来使用许多重定向 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;
}

并使用:

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

}

【讨论】:

  • 谢谢。 setInstanceFollowRedirects() 是我需要的。
  • 很好的解决方案。但为什么是 getHeaderField("Location")?谢谢
  • 这可以更笼统。事实上,它并不适用于所有情况,即当位置字段不是绝对 URL 而是相对 URL 时。在这种情况下,您应该将基本 URL 与位置标头连接起来。
【解决方案2】:
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;
}

【讨论】:

  • 这段代码会在循环中,因为在while循环中你不会用新的url改变连接对象,在第一次中断后添加这一行:connection.disconnect(); connection = (HttpURLConnection) new URL(finalUrl).openConnection();
【解决方案3】:

我的第一个想法是将instanceFollowRedirects 设置为false,或者改用URLConnection

在这两种情况下,都不会执行重定向,因此您会收到对原始请求的回复。获取 HTTP 状态值,如果是 3xx,则获取新的重定向值。

当然可能存在一系列重定向,因此您可能需要迭代直到到达真正的(状态 2xx)页面。

【讨论】:

  • 我试过了,但仍然没有给出正确的网址。我根据您在原帖中的建议编辑并添加了我尝试过的内容
【解决方案4】:

@user719950 在我的 MAC-OSX 上 - 这解决了 HTTP URL 被截断的问题:

在您的原始代码中,只需添加以下行: // 您必须通过浏览器查找 IE/Chrome 发送的请求标头是什么。我仍然没有解释为什么这个简单的设置会导致正确的 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();

【讨论】:

    【解决方案5】:

    这可能会有所帮助

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

    【讨论】:

      【解决方案6】:

      @JEETS 您的 fetchRedirectURL 函数可能不起作用,因为有多种用于重定向的 HTTP 代码。将其更改为范围检查,它将起作用。

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

      【讨论】:

        【解决方案7】:

        如果有多个重定向,这个会递归:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-07-11
          • 1970-01-01
          • 2014-12-07
          • 2021-09-15
          • 2011-03-05
          • 2014-02-22
          • 1970-01-01
          相关资源
          最近更新 更多