JSF在Android设备上流式下载,返回.htm文件 [英] JSF streamed download on android device returns .htm file

查看:127
本文介绍了JSF在Android设备上流式下载,返回.htm文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在Android设备上的网页中面临一个奇怪的问题。

I'm currently facing a weird problem in my webpage on android devices.

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

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

只要我使用我的桌面浏览器* Mozilla Firefox 10 **,一切都可以正常工作**,但一旦我更改到我的移动设备,那么(SGS II,Android 2.3.5)下载的结果取决于我正在使用的浏览器应用程序。

Everything works fine as long as I use my desktop browser *Mozilla Firefox 10.** but as soon as I change to my mobile device (SGS II, Android vers. 2.3.5) the result of the download depends on the browser-app I'm using.

Mozilla和Opera手机: / strong>

两者似乎都能正确地下载文件。

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

任何其他浏览器应用程序(内置的Dolphin HD,...):

下载一个名为< filename> .pdf ;文件名> .htm ,它们都代表一个 .htm - 显示页面的HTML源代码。

Any other browser-app (built-in, Dolphin HD,...):
Downloads a file either named <filename>.pdf or <filename>.htm which both represent a .htm-file showing the html-source of the page.

我试过的内容:


  • 使用 StreamedContent 方法出来的 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;
}


  • 将文件手动流式传输到页面,如here 。 (Thx到BalusC)

  • Streamed the file manually to the page as described here. (Thx 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(); 
    }  
    


  • 设置< a href = > 到文件的本地副本。

    (我目前正在使用< p:commandButton> 所以我必须使用执行重定向的方法,而不是返回一个String,但它可以两种方式)

  • Set an <a href=""> to a local copy of the file.
    (I'm currently using a <p:commandButton> so I've to use a method executing a redirect instead of returning a String but it works in 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);
    }
    

    即使在我的Android设备上,这种最终的方法也能正常工作,但我如果我可以避免它,因为该文件从WebDAV流式传输,我不得不保存每个文件到服务器,不希望。这将产生更多的IO加载,并迫使我手动清理。

    This final approach worked fine even on my android device but I do not want to go this route if I can avoid it because the file gets streamed from a WebDAV an I'd have to save each file to the server. This would produce more IO load and would force me to manually clean-up.

    方法 helper()。getWebDavFile Helper()。getWebDavFileManually 返回PrimeFaces使用的DefaultStreamedConten 或

    The methods Helper().getWebDavFile and Helper().getWebDavFileManually either return a DefaultStreamedConten used by PrimeFaces or a byte[] for my own approach.

    到目前为止我所了解的

    不幸的是我的问题的解决方案:)。

    经过多少小时的使用谷歌我发现有可能的一个双http-post-request
    的。这将导致Android的内部下载管理器(用于破坏文件下载的情况下)发送额外的状态丢失的后请求。

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

    这个博客(见 GET部分,POST,REST [UPDATE 20120208] )有人面临同样的问题。我已经尝试了这个博客上提到的所有方法,但没有成功。

    在这个论坛有人分析了与 WireShark 相同的行为,几乎得出了相同的结论。

    我没有找到任何更多的资源,所以我被困在这个。

    As described in this blog (see section GET, POST, REST [UPDATE 20120208]) there is someone facing the same problem. I've tried all approaches mentioned on this blog but didn't succeed.
    On this forum someone analyzed the same behavior with WireShark and got nearly to the same conclusion.
    I didn't found any more ressources so I'm stuck at this.

    我也发布在PrimeFaces 论坛只是为了确保没有关于< p:fileDownload> 组件。

    I've also posted on the PrimeFaces forum just to make sure that there aren't any known issues regarding the <p:fileDownload> component.

    我想知道什么:

    我是否缺少某些东西?

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

    Am I missing something?
    Is there any possibility to download a streamed file from an JSF (http-post operating) webpage on an android device?

    任何帮助/建议/信息将不胜感激!
    提前感谢

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

    推荐答案

    其他问题我终于得到了时间来回避这个问题。

    OK, after I've faced some other issues I finally got the time to chek back on this problem.

    在使用谷歌的时间里,我没有得到任何新的线索,已经在我的问题。

    After some more hours spended on using google I didn't got any new clues as already mentioned in my question.

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

    It still is the fact that some android browsers aren't able to handle POST request and return the appropriate file.

    因为我选择给出 servlet方法(如评论中所述,并描述这里)尝试构建我自己的http-GET请求。

    Because of that I choose to give the servlet-approach (as mentioned in the comments and described here) a try and construct my own http-GET-request.

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

    Andvoilà 任何 Android设备,无论使用哪种浏览器!

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

    再次感谢@BalusC指向正确的方向。

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

    如果我找到时间,我会尝试JSF-GET方法,但是起初我很高兴这个。

    If I find the time I'll try the JSF-GET approach, too but at first I'm happy with this.

    如果有有任何人面临同样的问题或能够提出另一种解决方案,我将不胜感激任何贡献!

    If there is anyone facing the same problem or able to suggest another solution I would appreciate any contribution!

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

    This helped me, I'll have Fun :D!

    这篇关于JSF在Android设备上流式下载,返回.htm文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆