<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <title>バリデーション</title>
    <link rel="stylesheet" href="/css/style.css" type="text/css" media="all" />
    
    
  </head>
  <body>
    <div class="header">
      <div id="pane.left-header" class="pane left">
        <div id="org.seasar.kvasir.cms.toolbox.customPop-2" class="pop org.seasar.kvasir.cms.toolbox.customPop">
          <div class="body"><div class="wiki">
<ul>
<li><a href="/" class="pageNotFound">（サイトトップ）</a></li>
<li><a href="/download">ダウンロード</a></li>
<li><a href="/news/" class="pageNotFound">新着情報</a></li>
<li><a href="/docs/" class="pageNotFound">ドキュメント</a></li>
</ul>
</div>
</div>
        </div>
      </div>
      <div id="pane.right-header" class="pane right">
        <div id="org.seasar.kvasir.cms.toolbox.loginPop-1" class="pop org.seasar.kvasir.cms.toolbox.loginPop">
          <div class="body">
<form method="post" action="/plugins/toolbox/login.do/docs/0.9.x/ref/validation">
    <div class="row">
      <span class="label">Name</span>
      <span class="textinput"><input type="text" name="name" size="12" value="" /></span>
    </div>
    <div class="row">
      <span class="label">Password</span>
      <span class="textinput"><input type="password" name="password" size="12" value="" /></span>
    </div>
    <div class="row">
      <span class="submit"><input type="submit" value="Login" /></span>
    </div>
</form>
</div>
        </div><div id="org.seasar.kvasir.cms.pop.loginUserPop-1" class="pop org.seasar.kvasir.cms.pop.loginUserPop">
          <div class="body"></div>
        </div>
      </div>
    </div>
    <div class="page-frame">
      <div id="pane.left-sidebar" class="pane sidebar-frame sidebar subcontent">
        <div id="org.seasar.kvasir.cms.toolbox.searchPop-1" class="pop org.seasar.kvasir.cms.toolbox.searchPop">
          <h2 class="title">Search</h2>
          <div class="body"><form class="simple" method="get" action="/plugins/toolbox/search.do">
  <input type="text" name="query" size="12" />
  <input type="submit" value="Go!" />
</form>
</div>
        </div><div id="org.seasar.kvasir.cms.toolbox.customPop-1" class="pop org.seasar.kvasir.cms.toolbox.customPop">
          <h2 class="title">メニュー</h2>
          <div class="body"><ul>
  <li><a href="/" class="pageNotFound">（サイトトップ）</a></li>
  <li><a href="/download">ダウンロード</a></li>
  <li><a href="/news">新着情報</a></li>
  
    
    
      <li>
        <a href="/docs/1.0.x">ドキュメント（1.0.x系）</a>
        
      </li><li>
        <a href="/docs/0.9.x">ドキュメント（0.9.x系）</a>
        
      </li>
    
  
  <li><a href="/roadmap">ロードマップ</a></li>
  <li><a href="https://www.seasar.org/issues/browse/YMIR">既知の不具合を閲覧する・不具合を報告する</a></li>
  <li><a href="https://www.seasar.org/svn/ymir/">SVNリポジトリ</a></li>
  <li><a href="http://svn.seasar.org/browse/?root=ymir">SVNリポジトリを閲覧</a></li>
</ul>
</div>
        </div>
      </div>
      <div id="pane.main" class="pane main">
      
        <div id="org.seasar.kvasir.cms.toolbox.breadcrumbsPop-1" class="pop org.seasar.kvasir.cms.toolbox.breadcrumbsPop">
          
          <div class="body"><ul>
  <li class="first"><a href="/">(TOP)</a></li><li><a href="/docs">ドキュメント</a></li><li><a href="/docs/0.9.x">ドキュメント（0.9.x系）</a></li><li><a href="/docs/0.9.x/ref">リファレンスマニュアル</a></li><li>バリデーション</li>
</ul>
</div>
        </div><div id="org.seasar.kvasir.cms.pop.contentPop-1" class="pop org.seasar.kvasir.cms.pop.contentPop">
          <h2 class="title">バリデーション</h2>
          <div class="body">
<ul class="information">
  
  <li>2008-09-16 12:56:02</li>
</ul>
<div class="content"><div class="document">
<p>Pageコンポーネントのアクション呼び出しの際にリクエストパラメータが正当であるかどうかを検証することができます。この処理を「パラメータチェック」または「バリデーション」と呼びます。Ymirではバリデーションは「<a class="reference" href="/doc/ref/constraintCheck">制約チェック</a>」の一種です（他の制約チェックの種類としては「<a class="reference" href="/doc/ref/permissionCheck">権限チェック</a>」があります）。</p>
<div class="section" id="e38390e383aae38387e383bce382b7e383a7e383b3e381aee68c87e5ae9a">
<h3><a name="e38390e383aae38387e383bce382b7e383a7e383b3e381aee68c87e5ae9a">バリデーションの指定</a></h3>
<p>バリデーションを指定するにはアノテーションを用います。詳細については「<a class="reference pageNotFound" href="/doc/ref/constraintCheck#e588b6e7b484e381aee68c87e5ae9a">制約の指定</a>」を参照して下さい。</p>
</div>
<div class="section" id="e587a6e79086e381aee8a9b3e7b4b0">
<h3><a name="e587a6e79086e381aee8a9b3e7b4b0">処理の詳細</a></h3>
<p>バリデーションはPageコンポーネントへの依存コンポーネントやリクエストパラメータがセットされた後、アクション呼び出しの前に行なわれます。バリデーションに失敗すると、アクションを呼び出す代わりに以下の処理が行なわれます。</p>
<ol>
<li>バリデーション失敗に関する詳細情報であるorg.seasar.ymir.Notesオブジェクトが「notes」というキーでHttpServletRequestオブジェクトのアトリビュートとしてセットされる。</li>
<li>Pageコンポーネントが<cite>_validationFailed(Notes)</cite>メソッドを持っている場合、1.で生成されたNotesオブジェクトを引数としてこのメソッドが呼び出される。なければ<cite>_validationFailed()</cite>メソッドがあれば呼び出される。</li>
</ol>
<p>なお、<cite>_validationFailed</cite>メソッドの呼び出しが行なわれた場合でも行なわれなかった場合でも<cite>_render</cite>メソッドは呼び出されます。</p>
<div class="section" id="notese382aae38396e382b8e382a7e382afe38388">
<h4><a name="notese382aae38396e382b8e382a7e382afe38388">Notesオブジェクト</a></h4>
<p>バリデーションに失敗した場合、その情報がorg.seasar.ymir.Notesオブジェクトにセットされます。バリデーションのためのアノテーションが複数指定されている場合は全てのバリデーションが行なわれ、失敗したものについてNotesオブジェクトに情報がセットされます。</p>
<p>Notesオブジェクトは1つまたは複数のorg.seasar.ymir.Noteオブジェクトをカテゴリ毎に保持しています。Noteオブジェクトはvalueとパラメータを保持しています。StrutsのActionMessagesとActionMessageと同じようなものと思っていただければいいと思います。</p>
<p>Note#getValue()の値（noteキー）はバリデーションの種類によって異なりますので、これを見ることで失敗したバリデーションが何か知ることができます。</p>
<p>バリデーション失敗に関するNoteオブジェクトは、そのバリデーションの対象であるリクエストパラメータ名と同じ名前のカテゴリに関連付けられてNotesオブジェクトに追加されます。</p>
</div>
<div class="section" id="e383a1e38383e382bbe383bce382b8e381aee8a1a8e7a4ba">
<h4><a name="e383a1e38383e382bbe383bce382b8e381aee8a1a8e7a4ba">メッセージの表示</a></h4>
<p>バリデーションエラーメッセージを表示するには、例えば以下のようにします。</p>
<p>まとめて表示する場合、</p>
<pre class="literal-block">
&lt;ul tal:condition=&quot;notes&quot;&gt;
  &lt;li tal:repeat=&quot;note notes/notes&quot; tal:content=&quot;note/%value&quot;&gt;MESSAGE&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>全体に関するメッセージを先頭に表示し、項目ごとのメッセージ項目ごとに表示する場合、</p>
<pre class="literal-block">
&lt;ul tal:condition=&quot;notes/size(org.seasar.ymir.GLOBAL_NOTE)&quot;&gt;
  &lt;li tal:repeat=&quot;note notes/org.seasar.ymir.GLOBAL_NOTE&quot; tal:content=&quot;note/%value&quot;&gt;GLOBAL MESSAGE&lt;/li&gt;
&lt;/ul&gt;
...
&lt;ul tal:condition=&quot;notes/size(param)&quot;&gt;
  &lt;li tal:repeat=&quot;note notes/param&quot; tal:content=&quot;note/%value&quot;&gt;MESSAGE FOR PARAM&lt;/li&gt;
&lt;/ul&gt;
</pre>
</div>
<div class="section" id="e383a1e38383e382bbe383bce382b8e381aee382abe382b9e382bfe3839ee382a4e382ba">
<h4><a name="e383a1e38383e382bbe383bce382b8e381aee382abe382b9e382bfe3839ee382a4e382ba">メッセージのカスタマイズ</a></h4>
<p>表示されるメッセージをカスタマイズするには、アプリケーションのsrc/main/resourcesにあるmessages.xpropertiesに書かれているプロパティのうち、noteキーと同じキーを持つものを変更して下さい。</p>
</div>
</div>
<div class="section" id="e38390e383aae38387e383bce382b7e383a7e383b3e381aee7a8aee9a19e">
<h3><a name="e38390e383aae38387e383bce382b7e383a7e383b3e381aee7a8aee9a19e">バリデーションの種類</a></h3>
<p>Ymirが標準で提供しているバリデーションは以下のとおりです。（アノテーションクラスはorg.seasar.ymir.constraint.annotationパッケージにあります。）</p>
<table border="1" class="docutils">
<colgroup>
<col width="24%" />
<col width="76%" />
</colgroup>
<thead valign="bottom">
<tr>
<th>アノテーション名</th>
<th>説明</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td>Length</td>
<td>
<p>リクエストパラメータ文字列の長さに関する制約を指定します。</p>
<p>制約の対象となるのは、propertyプロパティで指定されたリクエストパラメータと、アノテーションが付与されているSetterから導き出せるプロパティ名と同名のリクエストパラメータです。</p>
<p>noteキーは<tt class="docutils literal"><span class="pre">error.constraint.length</span></tt>です。</p>
<p>指定できるプロパティは以下のとおりです。</p>
<dl class="docutils">
<dt>property</dt>
<dd>対象となるリクエストパラメータ名。複数指定可能。</dd>
<dt>min</dt>
<dd>長さがここで指定したのと同じか長い必要があることを表します。</dd>
<dt>max, value</dt>
<dd>長さがここで指定したのと同じか短い必要があることを表します。valueよりもmaxの方が優先されます。</dd>
</dl>
</td>
</tr>
<tr>
<td>Numeric</td>
<td>
<p>リクエストパラメータが数値として解釈可能であるという制約を指定します。</p>
<p>制約の対象となるのは、valueプロパティとpropertyプロパティで指定されたリクエストパラメータと、アノテーションが付与されているSetterから導き出せるプロパティ名と同名のリクエストパラメータです。</p>
<p>noteキーは<tt class="docutils literal"><span class="pre">error.constraint.numeric</span></tt>です。</p>
<p>指定できるプロパティは以下のとおりです。</p>
<dl class="docutils">
<dt>value</dt>
<dd>対象となるリクエストパラメータ名。</dd>
<dt>property</dt>
<dd>対象となるリクエストパラメータ名。複数指定可能。</dd>
<dt>integer</dt>
<dd>値が整数値である必要があることを表します。デフォルトの値はtrueです。</dd>
<dt>greaterThan</dt>
<dd>値がここで指定したよりも大きい必要があることを表します。</dd>
<dt>greaterEqual</dt>
<dd>値がここで指定したのと同じか大きい必要があることを表します。</dd>
<dt>lessThan</dt>
<dd>値がここで指定したよりも小さい必要があることを表します。</dd>
<dt>lessEqual</dt>
<dd>値がここで指定したのと同じか小さい必要があることを表します。</dd>
</dl>
</td>
</tr>
<tr>
<td>Required</td>
<td>
<p>リクエストパラメータが必須である（nullや空文字列ではない）という制約を表します。</p>
<p>制約の対象となるのは、valueプロパティで指定されたリクエストパラメータと、アノテーションが付与されているSetterから導き出せるプロパティ名と同名のリクエストパラメータです。</p>
<p>noteキーは<tt class="docutils literal"><span class="pre">error.constraint.required</span></tt>です。</p>
<p>指定できるプロパティは以下のとおりです。</p>
<dl class="docutils">
<dt>value</dt>
<dd>対象となるリクエストパラメータ名。複数指定可能。</dd>
<dt>completely</dt>
<dd>同一名のパラメータが複数指定されている場合に、全てのパラメータが埋まっているべきかどうか。デフォルトはfalse。falseの場合は、複数のうちどれか1つだけでも埋まっていればバリデーションエラーにならない。</dd>
<dt>allowWhitespace</dt>
<dd>パラメータが空白文字（半角スペース、タブ、改行）だけからなる文字列を許容するかどうか。デフォルトはtrue。falseにすると、空白文字だけからなる文字列をバリデーションエラーとみなすようになる。</dd>
</dl>
</td>
</tr>
<tr>
<td>TokenRequired</td>
<td>
<p>リクエストパラメータとして渡されたトランザクショントークンがセッションに保持されているものと一致する必要があることを表します。</p>
<p>このアノテーションはクラスまたはアクションメソッドに付与して下さい。</p>
<p>noteキーは<tt class="docutils literal"><span class="pre">error.constraint.tokenRequired</span></tt>です。</p>
<p>指定できるプロパティは以下のとおりです。</p>
<dl class="docutils">
<dt>value</dt>
<dd>トークンを保持しているリクエストパラメータ名。省略した場合はデフォルトの名前が参照されます。</dd>
</dl>
</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="e3839ae383bce382b8e59bbae69c89e381aee38390e383aae38387e383bce382b7e383a7e383b3">
<h3><a name="e3839ae383bce382b8e59bbae69c89e381aee38390e383aae38387e383bce382b7e383a7e383b3">ページ固有のバリデーション</a></h3>
<p>独自にバリデーションのためのアノテーションと処理クラスを作成することでアプリケーション固有のバリデーションを実現することができますが、ページ固有のバリデーションの場合はわざわざアノテーションと処理クラスを作るのは大変です。そこでYmirでは、ページ固有のバリデーションをPageクラス内に書くことができるようになっています。</p>
<p>具体的には、返り値がorg.seasar.ymir.Notesであるようなメソッドまたはorg.seasar.ymir.constraint.ValidationFailedExceptionをスローするような返り値がvoidであるメソッドをPageクラスに追加して、org.seasar.ymir.annotation.Validatorアノテーションを付与することで、そのメソッドがバリデーションの際に呼び出されるようになります。</p>
<p>形式1:</p>
<pre class="literal-block">
@Validator
public Notes validate()
{
    if ([バリデーション失敗]) {
        return new Notes().add([リクエストパラメータ名], new Note(
            Constraint.PREFIX_MESSAGEKEY + [バリデート種別],
            new Object[]{ [リクエストパラメータ名] }));
    } else {
        return null;
    }
}
</pre>
<p>形式2:</p>
<pre class="literal-block">
@Validator
public void validate() throws ValidationFailedException
{
    if ([バリデーション失敗]) {
        throw new ValidationFailedException(
            new Notes().add([リクエストパラメータ名], new Note(
                Constraint.PREFIX_MESSAGEKEY + [バリデート種別],
                new Object[]{ [リクエストパラメータ名] })));
    }
}
</pre>
<p>バリデーションに失敗した場合は、返り値またはValidationFailedExceptionのコンストラクタの引数として、失敗情報に対応するNoteオブジェクトを含むようなNotesオブジェクトを指定するようにして下さい。バリデーションに成功した場合は、返り値がNotesのメソッドの場合は空のNotesオブジェクトを返すかnullを返すようにして下さい。</p>
<p>ボタンに関連付けられたアクションが呼び出されるケースでボタン名にパラメータが埋め込まれている場合、バリデータメソッドにも引数としてアクションに渡されるのと同じパラメータが渡されますので、パラメータを受けたい場合はバリデータメソッドに引数を定義して下さい。その際、それぞれの引数の型はアクションメソッドと同一にして下さい。</p>
<p>@Validatorアノテーションは複数のメソッドに付与することができます。また、あるアクションが呼び出される時だけバリデーションメソッドを動作させたい場合は、アノテーションの引数としてアクションメソッド名を列挙して下さい。アクションメソッド名を指定しない場合は全てのアクションに関してバリデーションが有効になります。</p>
</div>
</div>
</div>
</div>
        </div>
      
    </div>
    </div>
    <div class="footer-delimiter"></div>
    <div id="pane.footer" class="pane footer">
      <div id="org.seasar.kvasir.cms.pop.poweredByPop-1" class="pop org.seasar.kvasir.cms.pop.poweredByPop">
        <div class="body">Powered by Kvasir/Sora</div>
      </div>
    </div>
  </body>
</html>
