2012-03-12 74 views
3

我目前正在我的Android设备上的网页面临奇怪的问题。在Android设备上的JSF流下载返回.htm文件

我想要做的是允许用户下载PDF文件到他的移动设备。因此,我提供了一个下载按钮,如设置here所述。

一切正常,只要我使用我的桌面浏览器* Mozilla Firefox 10 **,但只要我改变到我的移动设备(SGS II,Android 2.3.5版)下载的结果取决于我使用的浏览器应用程序。

Mozilla和Opera移动:
似乎都能够正确地下载文件。

任何其他浏览器的应用程序(内置,海豚HD,...):
下载一个文件是命名<filename>.pdf<filename>.htm这两者都表示的.htm -file显示的HTML源这一页。

我已经试过:

  • 使用的StreamedContent方法出PrimeFaces

    public StreamedContent getFile() { 
        // prepare file for download 
        // reference webDAV directory and get file as stream 
        this.file = new Helper().getWebDavFile(customerId, fileName); 
    
        return file; 
    } 
    
  • 手动直播的文件页面描述here。 (感谢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(); 
    } 
    
  • 设置一个<a href="">到该文件的本地副本。
    (我目前使用一个<p:commandButton>所以我使用的方法执行重定向而不是返回一个字符串,但它在这两个方面的工作)

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

    这最后的方法工作得很好,即使我的Android设备上但我不希望去这条路线,如果我可以避免它,因为该文件从WebDAV流,我不得不将每个文件保存到服务器。这会产生更多的IO负载,并迫使我手动清理。

的方法Helper().getWebDavFileHelper().getWebDavFileManually要么返回DefaultStreamedConten通过PrimeFaces使用或的byte []我自己的方法。

我所知道的,到目前为止:

可惜不是我的问题:)解决方案。
经过了数小时的谷歌使用后,我发现有一个double-http-post-request的可能性。这会导致android内部下载管理器(用于发生文件下载失败的情况下)发送额外的状态丢失后请求。

this blog所述(请参阅第部分GET,POST,REST [UPDATE 20120208])有人遇到相同的问题。我尝试了在这个博客上提到的所有方法,但没有成功。
对此forum有人分析了相同的行为WireShark并得到了几乎相同的结论。
我没有发现任何更多的资源,所以我坚持这一点。

我也发布了PrimeFaces forum只是为了确保没有任何关于<p:fileDownload>组件的已知问题。

我想知道:

我缺少的东西?
有没有可能从Android设备上的JSF(http-post操作)网页下载流文件?

任何帮助/建议/信息将不胜感激!
在此先感谢!

+0

这是一个令人讨厌的问题。 POST *真的是强制性的吗?看起来这正是罪魁祸首。你也可以对JSF托管bean执行GET操作,尽管我宁愿为此使用一个简单的servlet。 – BalusC 2012-03-12 13:38:47

+0

@BalusC再次您好:)。不,POST不是*强制性的。请你详细说明你的建议。我很新的JSF和thougt我的视图参数(请参阅[链接](http://stackoverflow.com/questions/9584736/jsf-file-download-nullpointerexception-with-view-参数)的职位,你已经在哪里帮助我)足以执行GET。我也对* servlet *方法感兴趣。我会看看(看看)(http://balusc.blogspot.com/2007/07/fileservlet.html),看看我能不能帮助自己,但是我会赞赏你的任何着名的开球示例:)。谢谢,欢呼! – SimonSez 2012-03-12 15:04:55

回答

1

好的,在我遇到其他一些问题后,我终于有时间回味这个问题了。

经过一段时间的使用谷歌后,我没有得到任何新的线索,如我的问题中已经提到的。

它仍然是一些android浏览器无法处理POST请求并返回相应文件的事实。

正因为如此我选择给servlet的方法(如在评论中提到和描述here)尝试构建自己的HTTP-GET请求。

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

,瞧:下载上适用于任何 Android设备,无论使用哪种浏览器!

再次感谢@BalusC指引我朝着正确的方向前进。

如果我找到时间,我将尝试JSF-GET方法,但起初我对此感到满意。

如果有人遇到相同的问题或能够提出其他解决方案,我将不胜感激!

这帮了我,我会有乐趣:D!

0

有同样的问题。我使用primefaces.org的示例代码来下载带有移动设备的PDF。它在我的机器上工作正常,但不在iPad Safari或Android浏览器上。 问题已得到解决的陈列柜设置在实施例 - 控制器的内容类型:

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

其中仅用于图像的工作原理。那么,模式上的大脑:

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

现在一切工作正常。

+0

嘿,谢谢你的贡献!在项目开发过程中,我已经尝试过你的方法:没有成功。这时我正在使用PF Vers。 3.1。你能提供你正在使用的PF版吗? – SimonSez 2013-02-28 09:40:09

相关问题