0

I'm trying to add downloads to my Web Browser but the problem I got is to get the name of the file that you're trying to download. This is my code for downloading:

engine.locationProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                File file = new File(System.getProperty("user.home") + "/Downloads/Ekko Downloads/");
                String[] downloadableExtensions = {".doc", ".xls", ".zip", ".exe", ".rar", ".pdf", ".jar", ".png", ".jpg", ".gif"};
                for(String downloadAble : downloadableExtensions) {
                    if (newValue.endsWith(downloadAble)) {
                        try {
                            if(!file.exists()) {
                                file.mkdir();
                            }
                            File download = new File(file + "/" + newValue);
                            if(download.exists()) {
                                Dialogs.create().title("Exists").message("What you're trying to download already exists").showInformation();
                                return;
                            }
                            Dialogs.create().title("Downloading").message("Started Downloading").showInformation();
                            FileUtils.copyURLToFile(new URL(engine.getLocation()), download);
                            Dialogs.create().title("Download").message("Download is completed your download will be in: " + file.getAbsolutePath()).showInformation();
                        } catch(Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

The problem is here: File download = new File(file + "/" + newValue);

Instead of that newValue i need to get the name of that file.

Kiraged
  • 519
  • 2
  • 9
  • 28

2 Answers2

3

Ideally what you would be doing is intercepting calls at the network layer, and interpreting the content disposition MIME messages embedded in the HTTP traffic. Those messages can instruct the browser to download the file as an attachment with a provided filename. That is how you end up with some files being automatically downloaded based on an instruction sent from the server when you click on a link a browser.

Another thing browsers do is implement a kind of mime magic where they look at either the mime content type of the returned message, a deep inspection of the network traffic or just the extension prefix of a URL location to invoke a handler to download specific content types (you are doing only the later in your code).

The last way browsers handle downloads is you can right click on a page or link and choose Save As.

So, if you wanted a really robust fully functional browser like Chrome or Firefox you would do all of the above. As this horribly complicated test matrix shows, it is not really a particularly easy thing to do for all corner cases and even the big guys get it wrong.

Intercepting network traffic for WebView is possible but difficult. You can research other StackOverflow questions to do that - I won't address it here.

The same is also true of intercepting arbitrary web clicks, again search StackOverflow and it will turn up some questions on that, which might allow you to get right click to download functionality working.

So you are left with just intercepting location property changes as you are doing - obviously not ideal, but workable for many scenarios. That means you don't get filenames encoded in the content-disposition header, instead you have to parse the location url (just grab everything after the last /) and set that as the filename.

You can use the answers to the following question to derive the filename from the location URL:

Community
  • 1
  • 1
jewelsea
  • 150,031
  • 14
  • 366
  • 406
0

The WebView in JavaFX 8.0 will change status to "CANCELLED" when it cannot display a web page. This is generally an indication of a downloadable file, and you can inspect the location to make sure or filter what you want to download.

Next you can create a URL out of the location and do an HTTP HEAD request. This will allow you to get possible options for the filename based of the HTTP headers sent back. The headers may contain a header called Content-Disposition and the content may contain something like the following: attachment; filename="somfilename.ext".

So basically from there you can determine if you want to use the filename in the URL or the filename specified in the Content-Disposition header.