2010-09-03 81 views
2

我試圖下載如下頁面:http://structureddata.wikispaces.com/Test正在下載網頁。 OK用wget的,無法用java

wget的沒有任何選項失敗:

wget "http://structureddata.wikispaces.com/Test" 
(...) connect to session.wikispaces.com insecurely, use `--no-check-certificate' 

與--no檢查證書,它的工作原理現在

wget --no-check-certificate "http://structureddata.wikispaces.com/Test" 
grep Hello Test 
Hello World 

,我想下載的Java相同的URL,但下面的程序:

import java.net.*; 
import java.io.*; 
public class Test 
     { 
     public static void main(String args[]) 
       { 
       int c; 
       try 
         { 
         InputStream in=new URL("http://structureddata.wikispaces.com/Test").openStream(); 
         while((c=in.read())!=-1) System.out.print((char)c); 
         in.close(); 
         } 
       catch(Throwable err) 
         { 
         err.printStackTrace(); 
         } 
       } 
     } 

返回任何

我應該怎麼辦與Java下載頁?

非常感謝,

Ppierre

+0

有一些奇怪的現象:錯誤表明您使用的https與給定的URL不一致。我無法從wget重現消息。是否有涉及代理服務器? – 2010-09-03 18:03:33

回答

3

Java的URL接口是相當低的水平;它不會自動執行諸如重定向之類的操作。上面的代碼沒有打印出來的內容,因爲沒有內容。

通過執行類似下面的操作,您將看到您獲得的是HTTP 302響應 - 重定向。

URL url = new URL("http://structureddata.wikispaces.com/Test"); 

    URLConnection urlConnection = url.openConnection(); 
    Map<String, List<String>> headers = urlConnection.getHeaderFields(); 
    Set<Map.Entry<String, List<String>>> entrySet = headers.entrySet(); 
    for (Map.Entry<String, List<String>> entry : entrySet) { 
    String headerName = entry.getKey(); 
    System.out.println("Header Name:" + headerName); 
    List<String> headerValues = entry.getValue(); 
    for (String value : headerValues) { 
     System.out.print("Header value:" + value); 
    } 
    System.out.println(); 
    System.out.println(); 
    } 

我建議使用庫像HTTPClient這將處理更多協議的爲您服務。

(信貸,這是因爲:從here複製上面的代碼)

+1

它會自動遵循重定向,只有當它涉及不同的方案時纔會自動遵循重定向。通過'((HttpURLConnection)urlConnection).getFollowRedirects()'檢查自己。 – BalusC 2010-09-03 18:16:33

2

你可能想看看commons-httpclient,該代碼返回頁面沒有問題

final HttpClient client = new HttpClient(); 
final GetMethod method = new GetMethod("http://structureddata.wikispaces.com/Test"); 
try { 
    if (HttpStatus.SC_OK == client.executeMethod(method)) { 
     System.out.println(IOUtils.toString(method.getResponseBodyAsStream())); 
    } else { 
     throw new IOException("Unable to load page, error " + method.getStatusLine()); 
    } 
} finally { 
    method.releaseConnection(); 
} 
2

的問題是,它返回302重定向回覆到https網址。由於初始請求是http,目標是https,因此URLConnection不會自動遵循重定向(但它會在目標使用相同方案時執行)。

經過一番觀察,我得出結論,它會去https請求一些身份驗證令牌,然後將身份驗證令牌作爲請求參數再次重定向到http url。因此,它應該跟隨從httphttps,然後http的實際頁面內容的重定向。

以下工作在這裏。

public static void main(String... args) throws Exception { 
    // First request. 
    URLConnection connection = new URL("http://structureddata.wikispaces.com/Test").openConnection(); 

    // Go to the redirected https page to obtain authentication token. 
    connection = new URL(connection.getHeaderField("location")).openConnection(); 

    // Re-request the http page with the authentication token. 
    connection = new URL(connection.getHeaderField("location")).openConnection(); 

    // Show page. 
    BufferedReader reader = null; 
    try { 
     reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); 
     for (String line; ((line = reader.readLine()) != null);) { 
      System.out.println(line); 
     } 
    } finally { 
     if (reader != null) try { reader.close(); } catch (IOException ignore) {} 
    } 
} 

但是我同意Commons HttpComponents Client是一個更好的工具。