Serializable And Throwable Consumer

Wicket フォームイベント捕捉した時の処理は、シリアライズ化した関数型インターフェース
github.com
これのおかげで、Wicket 8から、AjaxFormSubmitBehavior の onSubmit でラムダ式を書けるようになった。
しかし、ラムダ式の中で例外捕捉の try~catchブロックを書いていくのも醜い。
そもそもラムダ式に記述する処理に例外が発生するような処理を書くべきではないのだが、
いた仕方ない場面も現実にはある。
→ それなら、Throwable で、Serializable を用意してまおうと考えました。
jdk-serializable-functionalを使います。

import java.util.Objects;
import java.util.function.Consumer;
import org.danekja.java.util.function.serializable.SerializableBiConsumer;
import org.danekja.java.util.function.serializable.SerializableConsumer;
/**
 * Serializable And Throwable Consumer.
 */
public interface SerialThrowableConsumer<T> extends SerializableConsumer<T>{
   
   default SerializableConsumer<T> andThen(Consumer<? super T> after
   , SerializableBiConsumer<T, Exception> onCatch){
      Objects.requireNonNull(after);
      return (T t)->{
         try{
            accept(t);
         }catch(Exception e){
            onCatch.accept(t, e);
         }
         after.accept(t);
      };
   }

   public static <T> SerializableConsumer<T> of(SerialThrowableConsumer<T> consumer
   , SerializableBiConsumer<T, Exception> onCatch){
      return t->{
         try{
            consumer.accept(t);
         }catch(Exception ex){
            onCatch.accept(t, ex);
         }
      };
   }

   public static <T> SerializableConsumer<T> of(SerialThrowableConsumer<T> consumer){
      return t->{
         try{
            consumer.accept(t);
         }catch(Throwable ex){
            throw new RuntimeException(ex);
         }
      };
   }
}

使用例、、、

queue(new Button("send")
.add(AjaxFormSubmitBehavior.onSubmit("click", SerialAndThrowableConsumer.of(t->{
   // t = AjaxRequestTarget
   label.setDefaultModelObject(infield.getValue());
   t.add(response);
}, (t, ex)->{
   t.add(response);
}))));

これを使う候補は、、、
AjaxFormSubmitBehavior.onSubmit
OnChangeAjaxBehavior.onChange
AjaxFormChoiceComponentUpdatingBehavior.onUpdateChoice
AjaxFormComponentUpdatingBehavior.onUpdate
AjaxEventBehavior.onEvent

例外を外側にださない方の of メソッド(以下)しか使わないかもしれない。

public static <T> SerializableConsumer<T> of(SerialThrowableConsumer<T> consumer
   , SerializableBiConsumer<T, Exception> onCatch)

また、ステートレスな Page ということであれば、
Wicket stateless なページ - Oboe吹きプログラマの黙示録
で書いた、CustomStatelessAjaxFormSubmitBehavior  を利用して、

ボタンクリックの振る舞いなどは、、、

queue(new Button("submit").add(CustomStatelessAjaxFormSubmitBehavior.onSubmit("click", SerialThrowableConsumer.of(t->{
     // form 送信 クリック、ステートレスな Pageでの処理
    // t = AjaxRequestTarget
}, (t, x)->{
    // x = 例外Exceprion
}))));

とまとめることができる。