10

レポート エクスポート ページの結果ページを作成したいと考えています。この結果ページには、エクスポートのステータスが表示され、このエクスポートのダウンロードが提供される必要があります。

エクスポートはアクション メソッドで行われます。経由で実行できcommandButtonますが、ロード時に自動的に実行する必要があります。

どうすればこれを達成できますか?

JSF:

<h:commandButton value="Download report" action="#{resultsView.downloadReport}"/>

バッキング Bean:

  public String downloadReport() {
    ...
    FileDownloadUtil.downloadContent(tmpReport, REPORT_FILENAME);
    // Stay on this page
    return null;
  }

明確化: これは a4j で実行可能ですか? Ajax リクエストが私のdownloadReportアクションをトリガーし、そのリクエストがファイルのダウンロードであるという解決策を考えました。

4

4 に答える 4

15

JSF 2.0 では、コンポーネント システム イベント、具体的には PreRenderViewEvent を使用してこれを解決することもできます。

レンダリングの前にダウンロード リスナーを起動するダウンロード ビュー (/download.xhtml) を作成するだけです。

<?xml version="1.0" encoding="UTF-8"?>
<f:view
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core">
    <f:event type="preRenderView" listener="#{reportBean.download}"/>
</f:view>

次に、レポート Bean (JSR-299 を使用して定義) でファイルをプッシュし、応答を完了としてマークします。

public @Named @RequestScoped class ReportBean {

   public void download() throws Exception {
      FacesContext ctx = FacesContext.getCurrentInstance();
      pushFile(
           ctx.getExternalContext(),
           "/path/to/a/pdf/file.pdf",
           "file.pdf"
      ); 
      ctx.responseComplete();
   }

   private void pushFile(ExternalContext extCtx,
         String fileName, String displayName) throws IOException {
      File f = new File(fileName);
      int length = 0; 
      OutputStream os = extCtx.getResponseOutputStream();
      String mimetype = extCtx.getMimeType(fileName);

      extCtx.setResponseContentType(
         (mimetype != null) ? mimetype : "application/octet-stream");
      extCtx.setResponseContentLength((int) f.length());
      extCtx.setResponseHeader("Content-Disposition",
         "attachment; filename=\"" + displayName + "\"");

      // Stream to the requester.
      byte[] bbuf = new byte[1024];
      DataInputStream in = new DataInputStream(new FileInputStream(f));

      while ((in != null) && ((length = in.read(bbuf)) != -1)) {
         os.write(bbuf, 0, length);
      }  

      in.close();
   }
}

それだけです!

ダウンロード ページ (/download.jsf) にリンクするか、HTML メタ タグを使用してスプラッシュ ページにリダイレクトすることができます。

于 2009-11-10T19:07:45.443 に答える
8

前の回答はフォームを送信し、おそらくナビゲーションを変更します。

<rich:jsFunction action="#{bean.action}" name="loadFunction" /> 次にwindow.onload=loadFunction;を使用します。

于 2009-11-08T09:05:26.770 に答える
3

要求ごとに 1 つの応答のみを送信できます。リクエストごとに 2 つの応答 (ページ自体とダウンロード ファイル) を送信することはできません。あなたができる最善のことは、ページのロード後にJavascriptを使用して(非表示の)フォームを送信することです。

window.onload = function() {
    document.formname.submit();
}
于 2009-11-06T11:11:37.103 に答える