スコープの制御

前からつけようと思ってつけてなかった。

まずはアノテーションの宣言

@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;
}

実際のソースはやたら冗長なロジックが目立つけど、まあやりたいことは出来てる。というかアノテーションの継承ができないのは痛い…。
あー、それよりも、毎回毎回インスタンスを生成してパラメータを弄くり廻すのはちょっとよろしくないですよね。。。どこかにプールしておく仕組みがあったほうが良いのかも。