SAStrutsとS2JDBCでの排他制御後の画面制御をhogeる
お蔵入りになったネタを放出。
SAStruts+S2JDBCで排他制御が発生したときにvalidateとかと同じような感じで
メッセージを出そうかという話があって、
でもActionの方でExceptionをいちいちcatchするのは面倒くさいなあということ
になって、
こんなネタを考えてみた。
まずはメッセージキーと引数を持つアノテーションを作ります。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Excl { /** key */ String key(); /** 引数 */ Arg arg0() default @Arg(key = ""); }
次に各Serviceでupdateメソッドを継承します。
このとき先程作ったアノテーションを付けます。
@Override @Excl(key = "message1", arg0 = @Arg(key = "labels.id")) public int update(User user){ return super.update(user); }
ほんでもって、serviceの実行時にinterceptorをかまして
OptimisiticLockExceptionがthrowされるた場合、OptimisticLockExceptionの代
わりに ActionMessagesExceptionをthrowします。
アノテーションの引数はActionMessagesExceptionの引数に使用します。
public class ExclInterceptor extends AbstractInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { Excl excl = invocation.getMethod().getAnnotation(Exclusive.class); if (excl != null) { try { return invocation.proceed(); } catch (OptimisticLockException lockException) { if (excl.arg0().key() != null && !excl.arg0().key().equals("")) { throw new ActionMessagesException(excl.key(), mesArg0); } else { throw new ActionMessagesException(excl.key()); } } } else { return invocation.proceed(); } } }
あとはcustomizer.diconに設定を追加しておくだけ。
<component name="serviceCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain"> <initMethod name="addCustomizer"> <arg>traceCustomizer</arg> </initMethod> <initMethod name="addCustomizer"> <arg> <component class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/> </arg> </initMethod> <initMethod name="addCustomizer"> <arg> <component class="org.seasar.framework.container.customizer.AspectCustomizer"> <property name="interceptorName">"ExclInterceptor"</property> </component> </arg> </initMethod> </component>
これでActionでいちいちtry-catchする必要が無くなります。
ただ、すべてのServiceでOverrideしなければいけませんが・・・。
結構これ面白いなと思っていたら、結局global-exceptionで一律でやっていいよ
という話になってお蔵入りしました。ショボーン