S2JSFでダーティリード対応
もう何度目だろう、S2JSFいじり。サンプル追ったり、前に作った軽いシステムの一部を実装してみたりとかしましたが、今回はサンプルの従業員管理画面を、サンプルをカンニングしつつ一から(S2JSFBlankからだけど)実装。
写経とはよくぞ云ったりですよ、本当。こう云うセンスって一番重要ですねぇ。
で、一昨日昨日であらかた動いたんですけど、versionNoでUpdateFailureRuntimeExceptionが出たときの対応がサンプルには無いんですねーこれが。ダーティリード対策は必須なので、やってみますか。
何処で例外を投げるか
サンプルだと、例えば検索条件が宜しく無くてヒット件数0の時、BadCriteriaRuntimeExceptionって自前の例外を投げてますが、これはActionクラスで行っています。
で、キャッチするのはActionThrowsInterceptorってアスペクトで各Actionクラスを横断してやっとる訳です。例外を受けて、そこからメッセージIDやらなにやら取って、JSFのFacesContext#addMessageにつめてます。
が、投げるのがActionでってのがどうにも落ち着かない。
完全webアプリならいいんですけど、同じ業務ロジックをRMIなりWebサービスなりで叩こうかって野望がある場合、処理が分散してしまいそうです。Actionクラスはあくまでも、Webプレゼンテーション層ですよね。JSFの画面IDが戻り値ですから。
特にダーティリード対策の場合、プレゼンテーション層で投げるのはどうにもこうにもアレです。それにActionクラスで投げたらActionThrowsInterceptorにつかまってしまい、無条件でJSF用のエラーメッセージを吐かれてしまいます。
JSF用メッセージは、JSFでしか使えません。多分。うーむ。
YAGNIですか。いいんです!ここは目をつむってGOだ。
んな訳で、取り敢えずBadCriteriaRuntimeExceptionを投げる所をActionクラスからLogicクラスへ移動してみました。
以下、削除コードは線を引いて、追加コードは太字です。ファウラー方式。
●EmployeeSearchActionImpl public String checkSearchCount() {if(employeeLogic.getSearchCount(employeeSearchDto) == 0){throw new BadCriteriaRuntimeException();}employeeLogic.getSearchCount(employeeSearchDto); return "employeeList"; }
●EmployeeLogicImpl public int getSearchCount(EmployeeSearchDto dto) {return employeeDtoDao.getSearchCount(dto);int searchCount = employeeDtoDao.getSearchCount(dto); if(searchCount == 0){ throw new BadCriteriaRuntimeException(); } return searchCount; }
結果は、ばっちり、例外はそのままActionクラスまで渡って、ActionThrowsInterceptorでキャッチされてJSFのエラーメッセージに表示されました。
これで方針は決まった。例外はLogicクラスで投げるどー。つづく。