2012-03-12 3 views
3

私は現在アンドロイドデバイスに関する私のウェブページで奇妙な問題に直面しています。アンドロイドデバイスのJSFストリーミングダウンロードは、.htmファイルを返します。

私がしたいのは、ユーザーが自分の携帯デバイスにpdfファイルをダウンロードできるようにすることです。したがって、私はhereの説明のようにダウンロードボタンを提供します。

デスクトップブラウザ* Mozilla Firefox 10 **を使用している限り、すべて動作しますが、モバイルデバイスに変更するとすぐに(SGS II、Androidバージョン2.3.5)ダウンロードの結果私が使っているブラウザアプリに依存します。

モバイルとモバイル:
どちらもファイルを正しくダウンロードできるようです。

他のブラウザアプリ(ビルトイン、イルカHD、...):
両方がのHTMLソースを示す-file .htmのを表す<filename>.pdf<filename>.htmという名前のいずれかのファイルをダウンロードしますページ。私が試した何

hereを説明するよう

  • 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; 
    } 
    
  • の外にStreamedContent方法を使用し、ページに手動でファイルをストリーミングさ。 (BalusCにThxを)

    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いずれかPrimeFacesや私自身のアプローチのための[]バイトが使用するDefaultStreamedContenを返します。私がこれまで知っている何

:残念ながら

ない私の問題の解決策:)。
Googleを何時間も使用した結果、ダブルhttp-post-requestの可能性があることが判明しました。これによりアンドロイド内部ダウンロードマネージャ(ファイルが壊れている場合に使用)が発生し、状態が失われた追加のポストリクエストが送信されます。

this blog

で説明したように(セクションGET、POST、REST [UPDATE 20120208]を参照)と同じ問題に直面して、誰かがあります。私はこのブログで言及したすべてのアプローチを試しましたが、成功しませんでした。
この場合forum誰かがWireSharkと同じ動作を分析してほぼ同じ結論に達しました。
もうリソースが見つかりませんでしたので、私はこれに固執しています。

また、<p:fileDownload>コンポーネントに関する既知の問題がないことを確認するため、PrimeFaces forumに投稿しました。

私が知りたいのですがどのような:

私は何かが足りないのですか?
アンドロイドデバイスのJSF(http-post操作)ウェブページからストリームファイルをダウンロードする可能性はありますか?

ご協力いただきありがとうございます。
ありがとうございます!

+0

これは厄介な問題です。 POST *は本当に必須ですか?それはまさに犯人のように見えます。また、JSFマネージドBeanでGETアクションを実行することもできますが、これは単純なサーブレットを使用していました。 – BalusC

+0

@BalusCこんにちは:)。いいえ、POSTは必須ではありません。あなたの提案を詳しく教えてください。私はJSFの新機能で、私のビュー・パラメータを使っています([リンク](http://stackoverflow.com/questions/9584736/jsf-file-download-nullpointerexception-with-view-parameter)の投稿を参照してください。私を助けた)GETを実行するのに十分でしょう。私は* servlet *アプローチにも興味があります。私は[look](http://balusc.blogspot.com/2007/07/fileservlet.html)を持ち、自分自身を助けることができるかどうかを見てみましょう。しかし、あなたの有名なキックオフの例はどれも評価されるでしょう:)。ありがとう、歓声! – SimonSez

答えて

1

私は他の問題に直面した後、ついにこの問題に取り組む時間がありました。

私の質問ですでに言及されているように私は新しい手がかりを得ていないGoogleを使用して過ごした後いくつかの時間。

アンドロイドブラウザの中には、POSTリクエストを処理して適切なファイルを返すことができないという事実もあります。そのための

は、私が(コメントで述べたと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

関連する問題