なんじゃくにっき

プログラミングの話題中心。

T2でValidator

 今月コード載せてないなってことで。
以前T2のプラグイン使った例書くとか言って放置していたので書く。
っていうか昨日のsoundTrickさんのエントリ見て、以前作ったのを思い出した。
http://d.hatena.ne.jp/soundTrick/20100321/1269157700
 
  
Struts等のFrameworkと違ってT2のポリシーとしてはValidatorは用意されてない。 
http://d.hatena.ne.jp/shot6/20080920#1221878799
 
ので、T2を使ったWEBアプリでValidationを行おうと思うと、
・T2と連携している別のFrameworkのValidatorを使う
・自前で実装
のどちらかになる。
 
 今回はDIコンテナ等を用いてないケースで
自作アノテーションとT2プラグインを使った例を書いてみる。
XMLを使っても勿論書けるが、T2自体がJava6以降必須だし、
アノテーションを使ってレスコンフィグにしましょうってことで。
 
Double型の値の範囲を指定して、範囲外の値が入力されたら例外を吐くものを作る。
 


メソッドの引数に付ける自作アノテーション
package t2validator.annotation;

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.PARAMETER)
public @interface DoubleValidator {
double maxVal() default 0.0;
double minVal() default 0.0;
}

 


Pageクラス。リクエストパラメータに自作アノテーション@DoubleValidator付与。
package t2validator.page;

import org.t2framework.commons.util.Logger;
import org.t2framework.t2.annotation.composite.GET;
import org.t2framework.t2.annotation.core.Default;
import org.t2framework.t2.annotation.core.Page;
import org.t2framework.t2.annotation.core.RequestParam;
import org.t2framework.t2.navigation.Forward;
import org.t2framework.t2.spi.Navigation;

import t2validator.annotation.DoubleValidator;

@Page("/example")
public class ExamplePage {
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(ExamplePage.class);

@GET
@Default
public Navigation get(@DoubleValidator(minVal=0.0, maxVal = 100.0)
@RequestParam("percentage")String percentage) {
return Forward.to("/WEB-INF/pages/example.jsp");
}
}

 

プラグイン
package t2validator.plugin;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.t2framework.commons.meta.MethodDesc;
import org.t2framework.commons.util.Logger;
import org.t2framework.t2.action.ActionContext;
import org.t2framework.t2.plugin.AbstractPlugin;
import org.t2framework.t2.spi.Navigation;

import t2validator.annotation.DoubleValidator;

public class ValidatorPlugin extends AbstractPlugin{
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(ValidatorPlugin.class);

@Override
public Navigation beforeActionInvoke(ActionContext actionContext,
MethodDesc targetMethod, Object page, Object[] args) {

Method method = targetMethod.getMethod();
Annotation[][] annotations = method.getParameterAnnotations();

for (int i = 0; i < args.length; i++) {
for (Annotation annotation: annotations[i]){
if (annotation.annotationType() == DoubleValidator.class){
double maxVal = ((DoubleValidator)annotation).maxVal();
double minVal = ((DoubleValidator)annotation).minVal();

if (maxVal != 0.0 || minVal != 0.0){
if (maxVal < Double.parseDouble((String)args[i])){
throw new IllegalArgumentException("引数が最大値を上回っています");
}

if (maxVal > Double.parseDouble((String)args[i])){
throw new IllegalArgumentException("引数が最小値を下回っています");
}
}
}
}
}

return getPluginDefaultNavigation();
}
}

 
これは範囲外の値が入力されたら例外を吐くようにしてあるが、
お好みでエラーページに飛ばすなど、どうぞ。