よりスマートな画面遷移?
先日、社内のRailsな人にSAStrutsのことを軽く説明する機会がありました。
以前のエントリーに書いた『画面に表示するデータを準備する』メソッドの
名前は遷移先のjspファイル名にあわせる、という非公式の私のお作法を説明した後に、
以下のようなコードを見てもらったのですが、どうも気に入らないと。
@Execute(validator = false) public String hoge() { return "hoge.jsp"; }
理由は次のとおり。
うーん、なるほど。一理ある。
ということで、以下のような感じで記述できる
インターセプター(ForwardByMethodNameInterceptor)を作ってみました。
このインターセプターを適用すると、
先ほどのコードは以下のように書き換えることが出来ます。
(一応、社内のRailsな人も納得でした。)
@Execute(validator = false) public String hoge() { return Forward.BY_MEHTOD_NAME; }
実行メソッドの戻り値がForward.BY_MEHTOD_NAMEだったら、
戻り値を「メソッド名 + ".jsp"」に差し替えるのが
ForwardByMethodNameInterceptor の機能です。
Forward.BY_MEHTOD_NAME はString型の定数です。
(このキーワードはより分かりやすいものに見直したいところ。)
元々、SAStrutsはURLとメソッドはCoCによりマッピングできるが、
これにより URLとメソッドとJSPファイルが簡単なルールにより
マッピングできることになります。
ForwardByMethodNameInterceptor 導入の
メリット・デメリットについて検討してみました。
【メリット】
- よりタイプセーフなコーディングが可能
- メンテナンス性の向上(JSPファイル名の変更があった時に、戻り値も一緒に修正する手間を省けるため)
- JSPファイルとメソッドのマッピングが明確となりソースコードの可読性UP
- 『画面表示用データ準備』メソッドと『画面入力データ処理』メソッドの責務が分離しやすくなる
- JSPファイル名から機械的に実行メソッドの雛形が作成可能となる
- フレームワークが押し付ける機能ではない。使いたい人が使えばよい自由さがある
【デメリット】
作成したソースコードは以下のとおり。
ForwardByMethodNameInterceptor.java
public class DefaultRoutingInterceptor extends AbstractInterceptor { /** * 遷移先のパスが Forward.BY_MEHTOD_NAME だったら、 * 戻り値を「メソッド名 + ".jsp"」に書き換えます。 */ public Object invoke(MethodInvocation invocation) throws Throwable { Object ret = invocation.proceed(); if (isExecuteMethod(invocation.getMethod())) { String navitationPath = ret.toString(); if (Forward.BY_MEHTOD_NAME.equals(navitationPath)) { return invocation.getMethod().getName() + ".jsp"; } } return ret; } protected boolean isExecuteMethod(Method method) { Execute execute = method.getAnnotation(Execute.class); if (execute == null || method.getParameterTypes().length > 0 || method.getReturnType() != String.class) { return false; } return true; } }
Forward.java
package tutorial.consts; public class Forward { public static final String BY_MEHTOD_NAME = "sastruts.Forward.BY_MEHTOD_NAME"; }
行き過ぎたCoCはNGですが、強要しないし、マッピング系のCoCはありだと思っています。