画面間情報引渡し

Clickを実案件でつかってて、画面間の値引渡しでちょっと悩んだ。
Click Frameworkな日々に書かれてる、「画面間情報引渡し」については、次の3つが提唱されています。

  • Context#setAttribute( )を使う方法。
  • リダイレクトするURLに直接指定する方法。
  • ページクラスに情報を引き渡すセッターを用意する方法。

やっぱりセッターを使う方法が一番しっくり来る。セッターというか、まぁ何かしらの値を直接Pageのインスタンスに渡す方法が。でもここで書かれてるけど「カッコ悪い」方法になっちゃうわけです。
というわけで、今のプロジェクトで採用した方法をこうかーい。

public class SomePage extends Page {
  //publicでメンバ変数で保持。
  //次のリクエストでonInit前に自動的にセットされる。
  //つまりonInitでもこの値を判断条件などに使える。
  public String hoge = "";

  @Override
  public void onRender() {
    //使用するフォームを渡す。
    saveFieldToForm(form);
  }
  protected void saveFieldToForm(Form form){
    Field[] fields=this.getClass().getFields();
    for (Field field : fields) {
      Class<?> type = field.getType();
      //ClickServletがPageのonInit前にpublicフィールドに値を
      //セットする条件をそのまま記述。
      if (type.isPrimitive()
          || String.class.isAssignableFrom(type)
          || Number.class.isAssignableFrom(type)
          || Boolean.class.isAssignableFrom(type)) {
        String name = field.getName();
        Object value = FieldUtil.getValue(this, field);
        //FormにHeddienFieldで登録して、次のリクエストで受け取れるようにする。
        form.add(new HiddenField(name, value));
      }
    }
  }
}

でも、全部のpublicフィールドを登録してちゃ効率わるいんで、何かしらの手段でフィールドを特定したい。今回はアノテーションを使用。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SaveField {
}

上記コードのif部分を、次のif文で囲む。

if (field.getAnnotation(SaveField.class) != null) {
}

メンバ変数はアノテーションつける。

@SaveField
public String hoge = "";

Java5じゃないとアノテーションが使えないのが痛いけど、こんな簡単な方法で開発はすごく楽になった。onRenderでsaveFieldToFormを呼ばなきゃってのがあれだけど、まぁそのぐらいは大目に見てもらってる。