Download file with Apache HttpClient

10,595

Solution 1

You can get the file name and extension from your response's content-disposition header

First get the header then parse it for the filename as explained here, i.e:

HttpEntity entity = response.getEntity();
if (entity != null) {
    String name = response.getFirstHeader('Content-Disposition').getValue();
    String fileName = disposition.replaceFirst("(?i)^.*filename=\"([^\"]+)\".*$", "$1");
    FileOutputStream fos = new FileOutputStream("C:\\" + fileName);
    entity.writeTo(fos);
    fos.close();
}

Solution 2

More formal way would be to use HeaderElements API:

    Optional<String> resolveFileName(HttpResponse response) {
        return Arrays.stream(response.getFirstHeader("Content-Disposition").getElements())
                .map(element -> element.getParameterByName("filename"))
                .filter(Objects::nonNull)
                .map(NameValuePair::getValue)
                .findFirst();
    }
Share:
10,595
retArdos
Author by

retArdos

Updated on June 04, 2022

Comments

  • retArdos
    retArdos almost 2 years

    what im trying to do is to download a file with httpclient. At the moment my code is the following.

        HttpClient client = HttpClientBuilder.create().build();
        HttpGet request = new HttpGet(downloadURL);     
    
    
        HttpResponse response = client.execute(request);
    
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            FileOutputStream fos = new FileOutputStream("C:\\file");
            entity.writeTo(fos);
            fos.close();
        }
    

    My download URL is something like that: http://example.com/file/afz938f348dfa3

    As you can see there is no extension to the file (in the url at least) however, when i go to the url with a normal browser, it does download the file "asdasdaasda.txt" or "asdasdasdsd.pdf" (the name is different from the url and the extenstion is not always the same, depends on what im trying to download).

    My http response looks like this:

    Date: Mon, 29 May 2017 14:57:14 GMT Server: Apache/2.4.10 Content-Disposition: attachment; filename="149606814324_testfile.txt" Accept-Ranges: bytes Cache-Control: public, max-age=0 Last-Modified: Mon, 29 May 2017 14:29:06 GMT Etag: W/"ead-15c549c4678-gzip" Content-Type: text/plain; charset=UTF-8 Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 2554 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive

    How can i do so my java code automatically download the file with the good name and extension in a specific folder ?

    • Ovidiu Dolha
      Ovidiu Dolha almost 7 years
      you might want this header but of course it really depends on how the file is being served from the server; show a sample of the plain HTTP response received when requesting the URL or provide a valid accessible URL you are using to be able to get more help
    • retArdos
      retArdos almost 7 years
      @OvidiuDolha Date: Mon, 29 May 2017 14:57:14 GMT Server: Apache/2.4.10 Content-Disposition: attachment; filename="149606814324_testfile.txt" Accept-Ranges: bytes Cache-Control: public, max-age=0 Last-Modified: Mon, 29 May 2017 14:29:06 GMT Etag: W/"ead-15c549c4678-gzip" Content-Type: text/plain; charset=UTF-8 Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 2554 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive
  • retArdos
    retArdos almost 7 years
    Thanks a lot, your code seems to be working fine. However i had coded a first version with this line: String fileName = disposition.substring(disposition.indexOf("\"") + 1, disposition.lastIndexOf("\"")); instead of String fileName = disposition.replaceFirst("(?i)^.*filename=\"([^\"]+)\".*$", "$1"); What is the difference between the two as they seem to be both giving the same result
  • Manu Manjunath
    Manu Manjunath about 6 years
    @retArdos Your way is simpler