2017-04-23 70 views
1

我試圖從網頁下載文件,同時繼續瀏覽同一網頁。Javafx webengine我無法同時下載和加載頁面

public class Main extends Application 
    { 

    String urlBrowser = ""; 

    @Override 
    public void start(final Stage stage) { 
     stage.setWidth(800); 
     stage.setHeight(500); 
     Scene scene = new Scene(new Group()); 

     final WebView browser = new WebView(); 
     final WebEngine webEngine = browser.getEngine(); 

     ScrollPane scrollPane = new ScrollPane(); 
     scrollPane.setContent(browser); 

     ebEngine.locationProperty().addListener(new ChangeListener<String>() { 
     @Override 
     public void changed(ObservableValue<? extends String> observableValue, String oldLoc, String newLoc) { 
      url = observableValue.getValue()); 
     } 
     }); 

     webEngine.getLoadWorker().stateProperty() 
      .addListener(new ChangeListener<State>() { 

      @Override 
      public void changed(ObservableValue ov, State oldState, State newState) { 
       if (newState == Worker.State.CANCELLED) { 
        if(urlBrowser.contains("download"){ 
         try{ 
          Download download = new Download(webEngine.getLocation()); 
          Thread t = new Thread(download); 
          t.start(); 
         }catch(Exception ex){ 
          ex.printStackTrace(); 
         } 
        } 
       } 
      }); 
      webEngine.load("http://www.website.com"); 
      scene.setRoot(scrollPane); 

      stage.setScene(scene); 
      stage.show(); 
     } 

     public static void main(String[] args) { 
      launch(args); 
     } 
    } 
} 


    public class Download implements Runnable{ 

    private final String urlPath; 
    private HttpURLConnection connection; 

    public Download(String url) { 
     this.urlPath = url; 
    } 

    @Override 
    public void run() { 
     try { 
      URL url = new URL(urlPath); 
      connection = (HttpURLConnection) url.openConnection(); 
      configConnection(); 
      download(); 
     }catch (MalformedURLException ex) { 
      ex.printStackTrace(); 
     }catch (IOException ex) { 
      ex.printStackTrace(); 
     }finally{ 
      if (connection != null) { 
       connection.disconnect(); 
      } 
     } 
    } 

    private void configConnection(){ 
     try { 
      connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"); 
      connection.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); 
      connection.setReadTimeout(0); 
      connection.setDoOutput(true); 
      try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) { 
       wr.writeBytes(parametrosFormulario); 
       wr.flush(); 
      } 
     }catch (ProtocolException ex) { 
      Logger.getLogger(DownloadFormPost.class.getName()).log(Level.SEVERE, null, ex); 
     }catch (IOException ex) { 
      Logger.getLogger(DownloadFormPost.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    private void download(){ 
     String contentDisposition = connection.getHeaderField("Content-Disposition"); 
     String url = connection.getURL().getHost(); 
     String saveFilePath = getFileName("src/test", contentDisposition, url); 

     FileOutputStream outputStream = null; 
     InputStream inputStream = null; 
     try{ 
      outputStream = new FileOutputStream(saveFilePath); 
      inputStream = connection.getInputStream(); 
      int BUFFER_SIZE = 10240; 
      int bytesRead = -1; 
      byte[] buffer = new byte[BUFFER_SIZE]; 
      while ((bytesRead = inputStream.read(buffer)) != -1){ 
       outputStream.write(buffer, 0, bytesRead); 
      } 
     }catch(FileNotFoundException ex){ 
      ex.printStackTrace(); 
     }catch (IOException ex) { 
      ex.printStackTrace(); 
     }finally{ 
      try { if (inputStream != null) inputStream.close(); } catch (IOException e) {} 
      try { if (outputStream != null) outputStream.close(); } catch (IOException e) {} 
     } 
    } 

    private String getFileName(String path, String contentDisposition, String url){ 
     String fileName = ""; 
     if (contentDisposition != null) { 
      int index = contentDisposition.indexOf("filename="); 
      if (index > 0) { 
       fileName = contentDisposition.substring(index + 9, contentDisposition.length()).replace("\"", ""); 
      } 
     } else { 
      fileName = url.substring(url.lastIndexOf("/") + 1, 
      url.length()); 
     } 
     return (path + File.separator + fileName); 
    } 
} 

一旦我在我想要的網站上,我導航到下載鏈接,我點擊並且程序開始下載。目前爲止這麼好,問題在於下載文件重量很大,在下載時我想繼續瀏覽頁面。當我點擊一個鏈接時,瀏覽器什麼也不做,只要下載完成,我就點擊鏈接。 我不知道發生了什麼,因爲下載我放在一個單獨的線程,但似乎瀏覽器不關心,並且不會讓我繼續瀏覽網站,直到我完成下載。

如何通過網頁免費下載導航?

謝謝!

+0

也許嘗試增加的值['http.maxConnections'](https://docs.oracle.com/javase/8/docs/technotes/guides/net/http-keepalive.html)。默認值是5,所以這可能沒有幫助... – jewelsea

+0

謝謝jewelsea迴應。我試圖增加連接數(我把65000!)但它沒有工作.... 瀏覽器保持在同一頁面,直到您完成下載文件。也許如果我創建另一個web引擎實例並執行下載功能。但我重申,這是非常奇怪的,因爲下載運行在一個單獨的線程上。我不知道還有什麼可以嘗試... – Loandoer

+1

嘗試使用下載功能的替代庫,例如[httpclient](https://hc.apache.org/httpcomponents-client-ga/)像這樣[示例] (https://gist.github.com/rponte/09ddc1aa7b9918b52029)。 WebView使用內部JDK URL連接,並且apache http客戶端不會,所以如果在WebView和您的自定義下載代碼之間的JDK的url連接邏輯中存在任何衝突,那麼如果您使用其他技術(當然這不會解決問題,如果問題與其他事情有關,但值得一試IMO)。 – jewelsea

回答

1

嗯,我試了Apache HttpClient庫,明白地做了和HttpURLConnection一樣的事情。 但使用JSoup我能夠實現我想要的。在下載過程中,我可以毫無問題地瀏覽網站。我留下了用於使用post方法從表單下載文件的代碼,以防有人爲您服務。謝謝jewelsea!

Response response = Jsoup.connect(url) 
        .method(Connection.Method.POST) 
        .ignoreContentType(true) 
        .timeout(0) 
        .data("user","user") 
        .data("pass","pass") 
        .execute(); 

String saveFilePath = "file.zip"; 
FileOutputStream outputStream = null; 
InputStream inputStream = null; 
try{ 
    outputStream = new FileOutputStream(saveFilePath); 
    inputStream = new ByteArrayInputStream(ByteBuffer.wrap(response.bodyAsBytes()).array()); 
    int BUFFER_SIZE = 1024; 
    int bytesRead = -1; 
    byte[] buffer = new byte[BUFFER_SIZE]; 
    while ((bytesRead = inputStream.read(buffer)) != -1) 
     outputStream.write(buffer, 0, bytesRead); 
}catch(FileNotFoundException ex){ 
    ex.printStackTrace(); 
}catch (IOException ex) { 
    ex.printStackTrace(); 
} catch (Exception ex) { 
    ex.printStackTrace(); 
}finally{ 
    try { if (inputStream != null) inputStream.close(); } catch (IOException e) {} 
    try { if (outputStream != null) outputStream.close(); } catch (IOException e) {} 
}