2

I am trying to download a file from a web page and at the same time continue browsing the same web page.

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

Once I am on the website that I want, I navigate to the download link, I click and the program starts the download. So far so good, the issue is that the download file weighs a lot and while I'm downloading I want to continue browsing the page. When I click on a link the browser does nothing and just when the download finishes go to the link that I clicked. I do not know very well what is happening because the download I put in a separate thread but it seems that the browser does not care and will not let me continue browsing the website until I finish the download.

How can I free the download of the navigation through the web page?

Thank you!

Minhaj Patel
  • 579
  • 1
  • 6
  • 21
Loandoer
  • 47
  • 1
  • 10
  • Perhaps try increasing the value of [`http.maxConnections`](https://docs.oracle.com/javase/8/docs/technotes/guides/net/http-keepalive.html). Default value is 5, so that may not help... – jewelsea Apr 23 '17 at 00:41
  • Thank you jewelsea for responding. I tried to increase the number of connections (I put 65000!) But it did not work .... The browser stays on the same page until you finish downloading the file. Maybe if I create another webengine instance and there perform the download functions. But I reiterate, it is very strange because the download is running on a separate thread. I do not know what else to try ... – Loandoer Apr 23 '17 at 05:06
  • 1
    Try using an alternate library for the download function, such as [httpclient](https://hc.apache.org/httpcomponents-client-ga/) like this [example](https://gist.github.com/rponte/09ddc1aa7b9918b52029). The WebView uses the internal JDK URL connection and the apache http client does not, so if there is any conflict in the url connection logic of the JDK between WebView and your custom download code, it won't appear if you use another technology (of course this won't fix the issue if the issue is related to something else, but is worth a try IMO). – jewelsea Apr 23 '17 at 06:38
  • Hi jewelsea! I tried with the apache httpclient library and it worked!!! The issue is that I am having problems to pass cookies from java.net.HttpURLConnection to Apache's HttpClient, since some downloads are made via a post form that needs session cookies.... – Loandoer Apr 23 '17 at 19:22
  • I was trying to load another page with webEngine.load () when the download starts and lets me navigate without problems (google, facebook, stackoverflow, etc) but it does not leave me on the webpage where I am downloading (http://www.website.com). Why can this be? – Loandoer Apr 23 '17 at 20:14

1 Answers1

1

Well, I tried the Apache HttpClient library and unmistakably did the same thing as HttpURLConnection. But using JSoup I was able to achieve what I wanted. While the download is taking place I can browse the website without any problem. I leave the code I used to download a file from a form with the post method, in case someone serves you. Thank you 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) {}
}
Loandoer
  • 47
  • 1
  • 10