スコープの制御
前からつけようと思ってつけてなかった。
まずはアノテーションの宣言
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Attribute { enum SCOPE{REQUEST, SESSION, APPLICATION} String name() default ""; SCOPE scope() default SCOPE.REQUEST; }
こんな感じでデフォルトはリクエスト・スコープ。
んで、アクションクラスではこういうふうに利用する。
public void Input { @Attribute(scope=Attribute.SCOPE.APPLICATION) private int hogeVar; }
まあ、特に難しいところはなし。
んで最後にパラメータから読み取るところと、パラメータに設定するところ。
パラメータから読み取る
Object value = null; // valueは取得した値を格納する switch (a.scope()) { // aはAttributeアノテーション case REQUEST: value = req.getParameter(valueKey); break; case SESSION: value = req.getSession().getAttribute(valueKey); break; case APPLICATION: value = this.getServletContext().getAttribute(valueKey); break; }
パラメータに設定
Object value = field.get( obj ); // fieldはアクションクラスでAttributeアノテーションをつけてるフィールドのこと value = (value == null) ? "" : value; // valueはパラメータに設定する値 switch (a.scope()) { case REQUEST: req.setAttribute(valueKey, value); break; case SESSION: req.getSession().setAttribute(valueKey, value); break; case APPLICATION: this.getServletContext().setAttribute(valueKey, value); break; }
実際のソースはやたら冗長なロジックが目立つけど、まあやりたいことは出来てる。というかアノテーションの継承ができないのは痛い…。
あー、それよりも、毎回毎回インスタンスを生成してパラメータを弄くり廻すのはちょっとよろしくないですよね。。。どこかにプールしておく仕組みがあったほうが良いのかも。