Downloadable streaming JSF load on android device returns .htm file

I am currently having a weird problem with my webpage on android devices.

What I want to do is allow the user to download the pdf file to their mobile device. Therefore, I provide a download button as described in here .

Everything works fine as long as I use my desktop browser * Mozilla Firefox 10. **, but as soon as I switch to my mobile device (SGS II, Android version 2.3.5), the download result depends on the browser app I am I use.

Mozilla and Opera mobile:
Both seem to be able to download the file correctly.

Any other browser application (built-in, Dolphin HD, ...):
Loads a file named <filename>.pdf

or <filename>.htm

that represents an .htm file showing the html source of the page.

What I have tried:

  • Used method StreamedContent

    from PrimeFaces library

    public StreamedContent getFile() {
        // prepare file for download
        // reference webDAV directory and get file as stream
        this.file = new Helper().getWebDavFile(customerId, fileName);
    
        return file;
    }
    
          

  • Manually stream the file to the page as described here . (thanks to BalusC)

    public void download() throws IOException {
    
        byte[] is = new Helper().getWebDavFileManually(customerId, fileName);
    
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
    
        ec.responseReset(); 
        ec.setResponseContentType("application/pdf");  
        ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileName.toUpperCase() + "\""); 
    
        OutputStream output = ec.getResponseOutputStream();
        output.write(is);
    
        fc.responseComplete(); 
    }  
    
          

  • Install <a href="">

    to a local copy of the file.
    (I am currently using <p:commandButton>

    , so I have to use a method that does a redirect instead of returning a string, but it works both ways)

    public void goToLink() throws IOException {
    
        // get WebDAV file and save temporarily
        byte[] b = new Helper().getWebDavFileManually(customerId, fileName);
        String path = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/") + fileName;
        File f = new File(path);
        try {
            FileOutputStream fos = new FileOutputStream(f);
            fos.write(b);
            link = "http://someurl/somepage/" + fileName;
        } 
        catch (FileNotFoundException e) {
            e.printStackTrace();
        } 
        catch (IOException e) {
            e.printStackTrace();
        }
    
        // use link
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        ec.redirect(link);
    }
    
          

    This final approach worked fine even on my Android device, but I don't want to go that route if I can avoid it, because the file is being transferred from WebDAV and I will need to save each file to a server. This will increase the I / O load and force me to manually clean up.

Methods Helper().getWebDavFile

and Helper().getWebDavFileManually

return DefaultStreamedConten used by PrimeFaces or byte [] for my own approach.

What I know so far:

Unfortunately not a solution for my problem :).
After many hours of googling, I found that there is a possibility of double http-post-request. This will cause the androids internal download manager (used in case of file download failure) to send an additional post request in which the state is lost.

As described in this blog (see GET, POST, REST [UPDATE 20120208]), there is someone facing the same issue. I've tried all of the approaches mentioned in this blog but didn't work. On this forum, someone analyzed the same behavior with WireShark and got almost the same output.
I haven't found any more ressources, so I'm stuck with this.

I also posted on the PrimeFaces forum to make sure there are no known issues regarding <p:fileDownload>

.

What I would like to know:

Am I missing something?
Is it possible to download a streaming file from a JSF webpage (http-post operating) on ​​an android device?

Any help / suggestion / information would be appreciated! Thanks in advance!

+3


source to share


2 answers


Ok, after running into some other problems, I finally got the time to answer this problem.

After a few hours spent using google I didn't have any new tips as mentioned in my question.

It still remains a fact that some android browsers are unable to handle the POST request and return the corresponding file.

Because of this, I choose to give the servlet approach (as mentioned in the comments and described here ) try and create my own http-get-requests.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    ...
    // Initialize servlet response 
    response.reset();
    response.setBufferSize(DEFAULT_BUFFER_SIZE);
    response.setContentType(mime);
    response.setHeader("Content-Length", String.valueOf(data.length));
    response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

    // write to response
    BufferedOutputStream output = null;
    try {
        output = new BufferedOutputStream(response.getOutputStream());
        output.write(data);
    }
    finally {
        output.close();
    }

      



And voilà: download works on any android device no matter what browser is used!

Thanks again @BalusC for pointing me in the right direction.

If I take the time, I'll try using JSF-GET, but I'm happy with it at first.

If anyone is facing the same problem or can suggest a different solution, I would appreciate any input!

It helped me, I have fun: D!

+1


source


had the same problem. I used sample code from primefaces.org to download PDFs using mobile devices. It worked fine on my machine, but not on iPad Safari or Android browsers. The problem was the content type in the example controller provided in the storefront:

file = new DefaultStreamedContent(stream, "image/jpg", "some.pdf");

      

Which only works for images. Well, the brain is in mode:



file = new DefaultStreamedContent(stream, "application/pdf", "some.pdf"); 

      

and everything works fine now.

0


source







All Articles