今回は、「Java EEで帳票をPDFで発行するのに色々悩んだ話」の二回目です。
Java EE + JSFで画面を作れるようになり、さらにJaspersoft Studioで帳票を開発し、Jasper Report Libraryを自分のプログラム(Mavenプロジェクト)に組み込み、開発した帳票をPDFで出力!!
やったぜ、出来たぜ!!と思ったら、そうは世の中甘くなかった。
PDFをブラウザにレスポンスとして返すと、確かに、PDFの出力は出来るわけです。
ブラウザが、「保存するのか、開くのか?」とか聞いてくれるわけです。
しかし、言ったら当然ですが、HTTPプロトコルの仕様ではレスポンスは1つしか返せない。
つまり、ブラウザにPDFのレスポンスを返してしまったら、その1つを使い切るわけで、画面のレスポンスは破棄されてしまう・・・つまり、画面は更新されない。
たとえば、PDFを発行したら、画面を「発行したよ!!」という状態に書き換える、という事が出来ない。
サーバー上にファイルとして出力して格納し、ダウンロード画面を出してあげて格納ファイルをダウンロード・・・というアイディアもあるけど、サーバー側にファイル書くのはちょっと最終手段としてとっておきたい。
というわけで、また悩んだあげく、処理を二回に分けてしまうのが一番簡単じゃないかな??と思い実行しました。
これでいいのか!?という問題はあるのですが、まぁ行けてる感じ。
二回に分けるとは、こういうことです。
■1回目の処理
(1-1)サーバー側でデータの更新を終わらせる。
(1-2)サーバー側で帳票のデータ作成を終わらせバイナリデータとして出力しておく。
(1-3)(2)のデータをセッションBeanに格納しておく。
(1-4)帳票が出来たよというフラグを立てておく。
(1-5)ブラウザにレスポンスを返し、画面を最新の状態に書き換える。
■2回目の処理
(2-1)ブラウザがロードされたら、JavaScriptで(1-4)のフラグを確認。立っていたら2回目の処理を自動実行。
※JSFの場合は、2回目の処理を実行する隠しボタンを作り、$('.隠しボタンクラス').click();とかするだけ。
(2-2)サーバー側で(1-3)のセッションBeanから作ってた帳票のバイナリを取り出す。
(2-3)取り出したPDFのバイナリを、ブラウザにレスポンスする。
(2-4)画面は書き変わらないが、1回目の処理で画面は書き換えているので問題なし。
という感じですね。
Primefases Extensionとか使えばもっと楽に出来るんでしょうけど、便利ライブラリ系の処理は、何かあると「こんな挙動だとやばい、知らなかった!!」的な事件に遭遇しやすいので、そんな難しい事じゃなければ、素直に自分で作り込みたい。
という感じでちょこちょこやっております。