画面間情報引渡し
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を呼ばなきゃってのがあれだけど、まぁそのぐらいは大目に見てもらってる。