Struts2をやってみる (13) -validationインターセプターを抑制する -
validateメソッドによる入力検証だったり、XML定義による入力検証っていうような方式がある。でこういう処理はフレームワークレベルで判断される訳だけど、これを抑制して自動で処理せずに自分でコントロールしたい場合とかの方法も用意されているようで
ちなみにStruts2のバリデーションインターセプターの実体はcom.opensymphony.xwork2.validator.ValidationInterceptorとなっている模様。でこちらで色々オプションなパラメーターがある模様
- programmatic: validateメソッドフローを行わない
- declarative: XML定義によるバリデーションフローをサポートしない
的な感じじゃないかなと。ってな訳で自分でコントロールする方式をやってみた
src/main/resources/sample/controllers/SampleAction-validation.xml
<?xml version="1.0" ?>
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<validator type="requiredstring">
<param name="fieldName">name</param>
<message>name is required</message>
</validator>
</validators>
これも作用しないけどとりあえず書いておく
SampleAction.java
package sample.controllers;
import com.opensymphony.xwork2.ActionSupport;
public class SampleAction extends ActionSupport {
private static final long serialVersionUID = 1L;
String name;
@Override
public void validate() {
// 実行されない
}
public String submit() {
return NONE;
}
public void setName(String name) {
this.name = name;
}
}
でここまでだと普通にアクションをstruts.xmlに定義した場合においても、validateメソッドも実行されるしXML定義なバリデーションフローをサポートされる。でこれらを無効にして、上記だとsubmitメソッドが作用する際に手動で検証を行いActionSupport.ERRORなりを出す事で入力画面に戻す的なことをやる。なのでちょっと上記のアクションを書き換える
package sample.controllers;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.lang3.StringUtils;
public class SampleAction extends ActionSupport {
private static final long serialVersionUID = 1L;
String name;
public String submit() {
if (StringUtils.isEmpty(name)) {
addFieldError("name", "required");
return ERROR;
}
return NONE;
}
public void setName(String name) {
this.name = name;
}
}
という感じで。でvalidateメソッドもフォローせずXML定義もフォローしない設定を行いこれをサポートさせる設定を行う
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="sample" extends="struts-default">
<action name="test" class="sample.controllers.SampleAction" method="input">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<result name="input">/WEB-INF/jsp/input.jsp</result>
<result name="success">/WEB-INF/jsp/input.jsp</result>
</action>
<action name="test-submit" class="sample.controllers.SampleAction" method="submit">
<interceptor-ref name="defaultStack">
<param name="validation.programmatic">false</param>
<param name="validation.declarative">false</param>
<param name="store.operationMode">STORE</param>
</interceptor-ref>
<result name="error" type="redirectAction">s
<param name="actionName">test</param>
</result>
</action>
</package>
</struts>
んまぁデフォルトなインターセプターのスタックにvalidationが入ってるのでそれのパラメーターをいじる感じでprogrammaticとdeclarativeをfalseにする。後者のdeclarativeをfalseにする事でXML定義なのはフォローされない模様。programmaticは別にvalidateメソッド実装していなければ良いんじゃないかと思うので
という感じでオプションパラメーターを使う事でデフォルトなバリデーションインターセプターが行う検証機構なフローをすっ飛ばして自分でコントロールする事も可能な模様
追記
@kinjou_j @SkipValidation でそのActionクラスのメソッドだけキャンセルできますね。
— A-pZ/ぢつにんさん/ヨーグリッター (@alpha_pz) 2013, 9月 27
との事