Java Springの逆引きメモ -8ページ目

Java Springの逆引きメモ

JavaのSpring frameworkのメモを書いていきます!
初心者の勉強ノートなので間違いがあるかもしれませんが、何かヒントになることがあれば幸いです。

前までの記事でSpring Modulesの使い方はだいたい大丈夫かと思います。


で。

実はこの機能は海外で作られたものなので日本語を判定する機能が無いのです。

つまり自作して設定しないといけません。


ここでは、自作のチェックの追加の仕方を見てみましょう!

題材は日本語のチェックです。


設定などは以前の記事を見てもらうことにして追加の仕方でけ見てみましょう。

 記事⇒ ・SpringModulesの機能について



【注意点】

最初に注意点を確認しましょう!

WEBなので必ずスレッドセーフに作ります。

これは忘れがちなので絶対に気をつけてください。




【チェックのクラス(/src/util/ValidateUtils.java)】

まず、全角かどうか?半角かどうか?などのチェックをするコードを書きます。

コードは1つの例なので、他の方法でもよいです。

ただし、引数の数と型は同じにしてください

 Errorsなどのクラスについては以下の記事が参考になると思います。

 ・Validatorでパラメタの妥当性チェックをするには?


また、Pattern はスレッドセーフなので、staticで使用しても問題ありません。

ですので以下のクラスのメソッドもスレッドセーフになっています!

package util;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.util.ValidatorUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springmodules.validation.commons.FieldChecks;

public class ValidateUtils {
 private static Pattern hankakuPattern =
               Pattern.compile("[\\p{InBasicLatin}]*");
 private static Pattern hiraganaPattern =
               Pattern.compile("[\\p{InHiragana}]*");
 private static Pattern katakanaPattern = 
               Pattern.compile("[\\p{InKatakana}]*");

 /**
  * 半角かどうかをチェックする。
  * @param bean
  * @param va
  * @param field
  * @param errors
  * @return
  */
 public static boolean validateHankaku (
  Object bean,
  ValidatorAction va,
  Field field,
  Errors errors
  ) {
  String value = null;
  
  if(bean == null){
   return true;
  }else{
   value = (String) ValidatorUtils.getValueAsString(bean,
                          field.getProperty());
  }
  
  if (!StringUtils.hasLength(value)) {
   return true;
  } 
  Matcher matcher = hankakuPattern.matcher(value);
  if(!matcher.matches()){
    FieldChecks.rejectValue(errors, field, va);
    return false;
  }
  
  return true;
 }

 /**
  * 半角チェック
  * @param str
  * @return
  */
 private static boolean isZenkaku(String str) {
  
  CharacterIterator iter = new StringCharacterIterator(str);
  
  for (char c = iter.first();
   c != CharacterIterator.DONE;
   c = iter.next()) {
   if (c <= 0x00FF) {
    //半角
    return false;
   }
  }
  return true;
 }


 /**
  * 全角かどうかをチェックする。
  * @param bean
  * @param va
  * @param field
  * @param errors
  * @return
  */
 public static boolean validateZenkaku (
  Object bean,
  ValidatorAction va,
  Field field,
  Errors errors
  ) {
  String value = null;
  
  if(bean == null){
   return true;
  }else{
   value = (String) ValidatorUtils.getValueAsString(bean, 
                        field.getProperty());
  }
  
  if (!StringUtils.hasLength(value)) {
   return true;
  } 
  if(!isZenkaku(value)){
    FieldChecks.rejectValue(errors, field, va);
    return false;
  }
  
  return true;
 }

 /**
  * 全角ひらがなかどうかをチェックする。
  * @param bean
  * @param va
  * @param field
  * @param errors
  * @return
  */
 public static boolean validateHiragana (
  Object bean,
  ValidatorAction va,
  Field field,
  Errors errors
 ) {
  String value = null;
  
  if(bean == null){
   return true;
  }else{
   value = (String) ValidatorUtils.getValueAsString(bean,
                        field.getProperty());
  }
  
  if (!StringUtils.hasLength(value)) {
   return true;
  } 
  Matcher matcher = hiraganaPattern.matcher(value);
  if(!matcher.matches()){
    FieldChecks.rejectValue(errors, field, va);
    return false;
  }
  
  return true;
 }

 /**
  * 全角カタカナかどうかをチェックする。
  * @param bean
  * @param va
  * @param field
  * @param errors
  * @return
  */
 public static boolean validateKatakana (
  Object bean,
  ValidatorAction va,
  Field field,
  Errors errors
  ) {
  String value = null;

  if(bean == null){
   return true;
  }else{
   value = (String) ValidatorUtils.getValueAsString(bean,
                        field.getProperty());
  }
  
  if (!StringUtils.hasLength(value)) {
   return true;
  } 
  Matcher matcher = katakanaPattern.matcher(value);
  if(!matcher.matches()){
            FieldChecks.rejectValue(errors, field, va);
            return false;
  }
  
  return true;
 }

}



【設定ファイルの設定(/WEB-INF/validator-rules.xml)】

globalタグの中の一番下に以下の記述を追記します。

javascript(クライアント側のチェックスクリプト)の設定は記述していないので各自で自由にお願いしますドキドキ



<!-- 半角チェック -->
<validator name="hankaku" classname="util.ValidateUtils"
method="validateHankaku"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.springframework.validation.Errors"

depends="" msg="errors.hankaku">

<javascript><![CDATA[ ]]>
</javascript>

</validator>


<!-- 全角チェック -->
<validator name="zenkaku" classname="util.ValidateUtils"
method="validateZenkaku"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.springframework.validation.Errors"

depends="" msg="errors.zenkaku">

<javascript><![CDATA[ ]]>
</javascript>

</validator>


<!-- 全角ひらがなチェック -->
<validator name="hiragana" classname="util.ValidateUtils"
method="validateHiragana"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.springframework.validation.Errors"

depends="" msg="errors.hiragana">

<javascript><![CDATA[ ]]>
</javascript>

</validator>


<!-- 全角カタカナチェック -->
<validator name="katakana" classname="util.ValidateUtils"
method="validateKatakana"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.springframework.validation.Errors"

depends="" msg="errors.katakana">

<javascript><![CDATA[ ]]>
</javascript>

</validator>



【メッセージリソース(/src/messages_ja.properties)】

メッセージリソースファイルには以下のキーを追記します。


errors.hankaku={0}は半角ですよ。
errors.zenkaku={0}は全角ですよ。
errors.hiragana={0}はひらがなですよ。
errors.katakana={0}はカタカナですよ。





【説明】
さて、上記の設定でしっかりチェック可能になっています。


参考までに、validation.xmlに記述する例を見てみましょう!


<field property="message" depends="maxlength,zenkaku">
<arg0 key="メッセージ" resource="false" />
<arg1 key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>10</var-value>
</var>
</field>



上記で、10文字以内かどうか? のチェックと、全ての文字が全角かどうか? のチェックをしてくれます。



<エラー時のメッセージ>

設定は以下のようになっています。


<!-- 全角チェック -->
<validator name="zenkaku" classname="util.ValidateUtils"
method="validateZenkaku"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.springframework.validation.Errors"

depends="" msg="errors.zenkaku">

<javascript><![CDATA[ ]]>
</javascript>

</validator>


  validateZenkakuのメソッドを呼び出してエラーだったら、「errors.zenkaku」をキーにして

  メッセージリソースから検索する、という設定になります。

  ですので、メッセージリソースに「errors.zenkaku」を設定しておく必要があります。




参考:

・トップ

・SpringModulesの機能について

・Validatorでパラメタの妥当性チェックをするには?



Strutsが分からない人は「何のことやら!?」って感じかもしれないですが。。シラー


はい。

Spring Modulesは、ファイルにオブジェクトの定義をするだけで書式チェックをしてくれるんです!

そのやり方を見ていきます。



【準備】

まず、モジュールのダウンロード、ファイルの設定などの準備をしてください。

以下のリンクのとおりに設定すれば大丈夫です。

 ・SpringModulesの機能について



準備できましたら、以下に進みましょう。



【WEBの用意】

WEBは以下のものを流用します。

もしまだ作ってない方は、作ってみてくださいませ!

 ・Validatorでパラメタの妥当性チェックをするには?


 ただし、Validatorは作成する必要はありません

 なぜならSpringModulesの機能を使用するからです。


 validatorは、「beanValidator」に書き換えてください!

---------------------

  <bean id="validatorTestInputController" class="org.springframework.web.servlet.mvc.SimpleFormController">
<property name="commandClass" value="business.domain.CmdTest" />
<property name="formView" value="/WEB-INF/jsp/input.jsp" />
<property name="successView" value="/WEB-INF/jsp/input.jsp" />
<property name="validator" ref="beanValidator"/>
</bean>

---------------------

 



【validator.xmlの設定(この記事でのメインです!)】

妥当性チェックするWEBがあった方がイメージが付きやすいと思うので載せておきますね。

チェックボックスがチェックされたときにテキストが入力されていないときにエラーにします。


  Java Springの逆引きメモ パラメタ名はそれぞれ、「display」、「message」です。

では、validator.xmlに以下を記述します。


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_1.dtd ">
<form-validation>

<formset>
<form name="cmdTest">

<!-- 必須チェック -->
<field property="display" depends="required">
<arg0 key="表示チェック" resource="false" />
</field>


<!-- 桁数チェック -->
<field property="message" depends="maxlength">
<arg0 key="メッセージ" resource="false" />
<arg1 key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>10</var-value>
</var>
</field>


<!-- displayがチェックされたときにmessageが空白のときにエラーとなる -->
<field property="message" depends="validwhen">
<arg0 key="メッセージ" resource="false" />
<arg1 key="表示チェック" resource="false" />
<msg name="validwhen" key="errors.requiredIfChecked"/>
<var>
<var-name>test</var-name>
<var-value>(((display == "true") and (message != null)) or (display == "false") )</var-value>
</var>
</field>
</form>
</formset>
</form-validation>


<formタグ>

クラス1つに対して1つのformタグを記述します。

<form name="cmdTest">

cmdTestは、チェック対象のクラス名の頭を小文字にしたものを記述します。

また、formタグは複数書けます。


<fieldタグ>

チェックする内容を記述します。

  <field property="display" depends="required">
   <arg0 key="表示チェック" resource="false" />
  </field>

これは、dependsがrequiredになっているので、必須チェックをしてくれます。

arg0は、エラーメッセージの{0}を表します。

上記の場合、「表示チェックは必須です」のようにエラーメッセージが出力されます。


おもしろいのは、validwhenです。

<field property="message" depends="validwhen">
<arg0 key="メッセージ" resource="false" />
<arg1 key="表示チェック" resource="false" />
<msg name="validwhen" key="errors.requiredIfChecked"/>
<var>
<var-name>test</var-name>
<var-value>(((display == "true") and (message != null))
or (display == "false") )</var-value>
</var>
</field>


式を使ってデータチェックをしています。

 (((display == "true") and (message != null)) or (display == "false") )

なんとなく分かりますよね。

nullは予約語でnullを表し、他の英数字はプロパティ名(getter名)を表します。

単純だし、結構便利ですよね!

ただし、項ごとに括弧を書かないといけません。そこがこれの難点です。


  <msg name="validwhen" key="errors.requiredIfChecked"/>
は、errors.requiredIfCheckedをエラーメッセージとして使用することを表します。




【メッセージリソースの設定(messages_ja.properties)】

あとは、メッセージリソースに追記してください。

上記でerrors.requiredIfCheckedを参照しているので、以下のメッセージを追記します。


errors.requiredIfChecked={0}は、{1}がチェックされた場合必須です。



【説明】

既に、参考にした以前の記事のWEBを動かしたことがある人は、同じ動きをすることが分かるでしょう。


ファイルにしているので、見通しがよく変更がしやすいですよね!


じゃんじゃん使っていきましょうー。




参考:

・トップ

・Validatorでパラメタの妥当性チェックをするには?

・SpringModulesの機能について

・SpringMVCの機能について



ここでは、オブジェクトの書式チェックをするSpring Modulesを見ていきます。


機能は、StrutsのValidationの機能とほぼ同様です。

実は裏で使っている機能はStrutsもSpring Modulesも同じなんです。

でも、URLのチェックがないことや日付型の設定方法が違うなど、Strutsと違うところもあるようなので注意です!


Strutsを使ったことない方もいるかと思うので、具体的に見ていきましょう!



【ダウンロード】

まずは、jarファイルをダウンロードしましょう!

https://springmodules.dev.java.net/


 現状の最新版は、0.9です。


依存ファイルもダウンロードしておきましょう!

(バージョンは最新のものでも動作すればいいと思うので動かしながら試してみてください!)

Commons Validator 1.3.1

Commons Digester 1.8

Commons BeanUtils 1.6

Commons Lang 2.3

Commons Collections 3.2

Jakarta Oro 2.0.8

Antlr 2.7.5




【設定】

まず必要なファイルを確認しておきましょう。


 ①/WEB-INF/validator.xml

 ②/WEB-INF/validator-rules.xml

 ③/src/messages_ja.properties


 spring-modules-0.9-all.jarなどのライブラリはすべて、libに入れておきましょう。


 

 ①は、自分で設定するファイルで、オブジェクトの書式を記述します。

 ②は、ダウンロードしたファイルの中のsampleからコピーすればよいでしょう。

  例えば、spring-modules-validation-commons-samples-src\webapp\WEB-INF\ とか。

  このファイルの役割は、書式チェックのルールを決めるものです。

  例えば、"required"が必須を表し、エラーになった場合はメッセージリソースの"errors.required"の

  エラーメッセージを出力する、などのルールです。

  あとで、具体例をみてみましょう!

 ③メッセージリソースです。

  以下のキーを設定しておけばとりあえずそれなに動くと思います。


errors.required={0}は必須です。
errors.requiredAtLeast={0}はいずれか必須です。
errors.maxlength={0}は{1}文字以内で入力してください。
errors.minlength={0}は{1}文字以上で入力してください。
errors.integer={0}は整数で入力してください。
errors.float={0}は小数です。
errors.double={0}は小数です。
errors.date={0}は正しい日付ではありません。
errors.range={0}は{1}と{2}の範囲でないといけません。
errors.creditcard={0}は不正なクレジットカード番号です。
errors.email={0}は不正なメールアドレスです。
errors.invalid={0}は不正です。




【具体的な例(validator.xml)】

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_1.dtd ">
<form-validation>


<formset>
<form name="member">


<!-- 必須チェック -->
<field property="id" depends="required">
<arg0 key="ID" resource="false" />
</field>


<!-- 桁数チェック -->
<field property="age" depends="maxlength, integer">
<arg0 key="年齢" resource="false" />
<arg1 key="${var:maxlength}" resource="false" />
<var>
<var-name>maxlength</var-name>
<var-value>2</var-value>
</var>
</field>


<!-- 日付フォーマットチェック -->
<field property="regDate" depends="date">
<arg0 key="登録日" />
<var>
<var-name>datePattern</var-name>
<var-value>yyyy/MM/dd</var-value>
</var>
</field>
</form>
</formset>
</form-validation>



上記をみると

 <field property="name" depends="required">

と記述してます。

このrequiredがvalidator-rules.xmlに定義されています。

単純にどのメソッドを使用してチェックするか?が記述されているだけなので

自作で作ったチェックのメソッドも簡単に追加できます!


  

 ※上記では、require, date などを使っています。

  その他にも、email, byteや、validwhenのように自由に条件をつけられるものもあります!





【Springファイル上の設定(/WEB-INF/applicationContext-other.xml)】

記述は、test-servlet.xmlなどのservlet系のSpring設定ファイルに記述してもよいのですが、

個人的には別ファイルにしておいた方がいいかと思っています。

というのは、junitを使用してテストするときに実行時のカレントパスが違うのでvalidator.xmlなどを見つけられないからです。

別ファイルにしておき、junit実行時はそのファイルだけ他のファイルを使用するようにするといいでしょう。


<!--validator 用の設定 -->
<bean id="validatorFactory"
class="org.springmodules.validation.commons.DefaultValidatorFactory">
<property name="validationConfigLocations">
<list>
<value>/WEB-INF/validator-rules.xml</value>
<value>/WEB-INF/validator.xml</value>
</list>
</property>
</bean>


<bean id="beanValidator"
class="org.springmodules.validation.commons.DefaultBeanValidator">
<property name="validatorFactory" ref="validatorFactory"/>
</bean>



<上記ファイルのためのweb.xmlの設定>

※上記ファイルを追加したら、WEB読み込むようにweb.xmlにファイル名を追記してください。

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml /WEB-INF/applicationContext-other.xml</param-value>
</context-param>




【Spring-servletファイルの設定(/WEB-INF/xxx-servlet.xml)】

servlet用のSpring設定ファイルにメッセージリソース用の設定をします。

SpringModulesでは基本的には、エラーメッセージをメッセージリソースに記述するので、

メッセージリソースを読み込めるようにしておかなければいけません。

その設定が以下の記述です。


<!--
 メッセージリソースの設定。
 bean名はmessageSourceにする必要があります。
-->

<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"/>
</bean>




あとは、SimpleFormControllerなどのvalidatorに上記で設定したbeanValidatorを設定するだけです!

簡単ですね!


<記述例>

<!-- サンプルController -->

<bean id="validatorTestInputController" class="org.springframework.web.servlet.mvc.SimpleFormController">
<property name="commandClass" value="business.domain.CmdTest" />
<property name="formView" value="/WEB-INF/jsp/input.jsp" />
<property name="successView" value="/WEB-INF/jsp/output.jsp" />
<property name="validator" ref="beanValidator"/>
</bean>


SimpleFormControllerやvalidatorが良く分からない人は、こちらの記事を見てみてくださいね。

 ・Validatorでパラメタの妥当性チェックをするには?








参考:

・トップ

・Strutsのように設定ファイルでパラメタの妥当性チェックをするには?

・日本語の妥当性チェックを追加するには? (独自のチェックの追加の仕方)

・Validatorでパラメタの妥当性チェックをするには?

・SpringMVCを使用してWEBを作るには? (実践編) : (パラメタとオブジェクトのバインドの方法)

SpringModulesのHP

SpringModulesの入力チェックを知る (ITPro)



'2012.03.23 追記

このブログで扱っているSpringMVCのバージョンは2.5で、情報が古くなっています。

現状、アノテーションを使用してかなり柔軟で使いやすくなっていますにひひ

この記事を削除することはしませんが、最新の情報を検索されることをお勧めします。

Spring MVC 3.xについて(日本語の記事)



-----------------------

基礎編ではAbstractCommandクラスを使用しましたが、実際にはSimpleFormControllerを使用することでほとんどのケースで事足ります。

 ・SpringMVCを使用してWEBを作るには? (基礎編)



ここでは、SimpleFormControllerクラスを使用してみましょう。


SimpleFormControllerは、パラメタとオブジェクトのバインドの方法でもあります。

それはJSPファイルとSpring設定ファイルによって簡単に実現できます。

同時にその方法も確認してみてください!ニコニコ



【SimpleFormControllerクラスの動作】

このクラスは、2つの画面を遷移するようなケースがデフォルトの動きです。

もちろん1つの画面に対しても使用できます。


例:

 データ登録画面を考えて見ます。

 ①データの入力項目を入力します。

 ②登録ボタンを押すと登録がされて、登録完了画面が表示されます。


 このとき入力項目がエラーだった場合、①の入力画面に戻って書式エラーを表示します。



上記例におけるSimpleFormControllerの動作:

 ①データ入力画面をshowForm()を使用して表示します。

  SimpleFormControllerはデフォルトでは、参照画面とデータ登録系画面を分けて考えています。

  showForm()は参照系の画面に対して呼ばれます。

  参照系か登録系かの判断は、methodのPOST/GETを利用して決めます。

  GETのときに参照系とみなします。

  また、Validatorも起動しません。


 ②登録完了画面をonSubmit()を使用して表示します。

  このメソッドはPOSTのときに呼ばれます。

  onSubmit()メソッドが呼ばれる前に、Validatorで妥当性チェックと、

  指定のModelクラス(Commandと呼びます)に値を設定する処理が実施されます。

  ValidatorやCommandクラスへの値設定で失敗した場合はエラー画面に遷移します。

 

 このように、基本的にはPOST/GETによって2画面のうちどちらの処理を起動させるかを決めています。



 <補足>

 さきほども書きましたが、1画面に対してもGET/POSTどちらも同じ処理をするようにもできます。

 その方法は、継承したクラスで下記のようにメソッドを上書きすればよいです。


 protected boolean isFormSubmission(HttpServletRequest request) {
  return true;
 }


  isFormSubmissionが2画面の処理のうちどちらの処理を起動するかを決めています。





【SimpleFormControllerサンプル】


package presentation;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import business.domain.CmdTest;

public class TestFormController extends SimpleFormController {
 @Override
 protected ModelAndView onSubmit(HttpServletRequest request,
   HttpServletResponse response, Object command, BindException errors)
   throws Exception {
  //
  CmdTest obj = (CmdTest)command;
  String msg = obj.getMessage() + "すてきなメッセージ☆";

  ModelAndView modelAndView
   = new ModelAndView(getSuccessView(), getCommandName(), command);
  modelAndView.addObject("convertedMsg", msg);
  
  return modelAndView;
 }
 
}




【入力画面(/WEB-INF/jsp/input.jsp)】

パラメタとオブジェクトのバインドについて。

下記の青字の部分がバインドと関係する部分です。

formタグになっていますが、別にformタグでなくとも普通のhtmlタグで大丈夫です。

結局、パラメタ名とオブジェクトのプロパティ名(getterの名前)が同じであればバインドされるのです。


<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"% >
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags " %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form " %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd ">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>入力テスト</title>
</head>
<body>
validatorControllerテスト<br>

<br>
<form:form method="post" >

<form:errors path="*" cssStyle="font-weight: bold; color: red;"></form:errors>
<br><br>

<form:checkbox path="display"/>

メッセージを表示します<br>

<form:input path="message"/>

<input type="submit" value="入力">
</form:form>
</body>
</html>



【完了画面(/WEB-INF/jsp/output.jsp)】

<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"% >

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd ">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>入力テスト</title>
</head>
<body>
CmdControllerテスト<br>
表示がTRUEのときにメッセージを表示します。<br>
<br>
<c:if test="${command.display}">
メッセージ:<c:out value="${convertedMsg}"/>
</c:if>
</body>
</html>




【Spring設定ファイル(一部抜粋)】

<bean id="validatorTestInputController" class="presentation.TestFormController">
<property name="commandClass" value="business.domain.CmdTest" />
<property name="commandName" value="command" />
<property name="validator" >
<bean class="validator.CmdTestValidator"/>
</property>
<property name="formView" value="/WEB-INF/jsp/input.jsp"/>
<property name="successView" value="/WEB-INF/jsp/output.jsp"/>
</bean>



formViewが、参照系の画面showForm()が呼ばれたときに表示するJSP。

successViewが、登録系の画面onSubmit()が呼ばれたときに表示するJSP。



 パラメタとオブジェクトのバインドについて:

  バインドの処理はSimpleFormController が実施しています。

  どのクラスにバインドするかは、commandClassに設定しています。

  バインドするクラスも設定ファイルの記述だけで変更できますね!
  

  バインドするオブジェクトと妥当性チェックの関係は以下の記事を参照ください。

  ・Validatorでパラメタの妥当性チェックをするには?



【その他の設定】

その他のクラスは、CmdTestクラス、Validatorクラスなどがありますが、

ここではその説明はメインではないので、下記の記事を参考にしてください。

そのままコピーして動作するはずです!

 ・Validatorでパラメタの妥当性チェックをするには?





どうでしょう。なんとなく分かりましたでしょうか?



参考:

・トップ

・SpringMVCの機能について

・SpringMVCを使用してWEBを作るには? (基礎編)

・Validatorでパラメタの妥当性チェックをするには?

・Springを使用するには?

・SpringでWEB作成するには?(基本的な作成例)

SpringMVCの基本を知る







'2012.03.23 追記

このブログで扱っているSpringMVCのバージョンは2.5で、情報が古くなっています。

現状、アノテーションを使用してかなり柔軟で使いやすくなっていますにひひ

この記事を削除することはしませんが、最新の情報を検索されることをお勧めします。

Spring MVC 3.xについて(日本語の記事)



---------------------------

Springでは妥当性チェックの方法をいくつか用意しています。

主には以下の2つかと思います。


 ①Vallidatorクラスを継承する方法

 ②Spring Modulesを使用する方法


ここでは、①の方法を見てみます。

②の方法は別の記事で見てみようと思います。(・SpringModulesの機能について

ほとんどの場合、WEBであれば②の方法で問題ないと思いますが、何か特殊なチェックをする場合は①の方法も知っておいた方がいいでしょう。



では、早速見てみましょう。

ここではValidatorの説明をメインとしたいため、Validator以外はあまり意味のない設定をしているので

Validator以外は気にせずに見てみてください。



【Validatorクラス】

妥当性チェックをします。
チェックボックスがチェックされているときにメッセージがnullならエラーとします。

Validatorクラスがチェックできるのは1つのオブジェクトだけです。

それを規定しているのがsupportsメソッドです。

Spring設定ファイルの読み込み時にこのメソッドをチェックしていて、falseのときエラーになります。

package validator;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import business.domain.CmdTest;
public class CmdTestValidator implements Validator {
 @Override
 /**
  * 対象のオブジェクトがこのクラスが対象とするクラスかをチェックする。
  */
 public boolean supports(Class clazz) {
  return CmdTest.class.isAssignableFrom(clazz);
 }

 @Override
 /**
  * 妥当性チェックをする。
  * ここでは、displayチェックがされたときに
  * messageに値が入っているかをチェックします。
  */
 public void validate(Object obj, Errors errors) {
  CmdTest cmd = (CmdTest)obj;
  if(cmd.isDisplay()){
   if(!StringUtils.hasLength(cmd.getMessage())){
    errors.rejectValue("message", 
      "error.required", "メッセージは必須です");
   }
  }
 }

}






【Spring設定ファイル(test-servlet.xml)】

ここではSimpleFormControllerを使用します。

submitすると同じ画面に遷移するようにします。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop.xsd
  http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx.xsd
  http://www.springframework.org/schema/util
 http://www.springframework.org/schema/util/spring-util.xsd
">

 <!-- 
  メッセージリソースの設定。
  bean名はmessageSourceにする必要があります。
 -->
 <bean id="messageSource"
  class="org.springframework.context.support.ResourceBundleMessageSource">
  <property name="basename" value="messages"/>
 </bean>
 <!-- HandlerMapping -->
 <bean id="handlerMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/input.html">validatorTestInputController</prop>
            </props>
        </property>
 </bean>

 <!-- サンプルController -->
 <bean id="validatorTestInputController"
  class="org.springframework.web.servlet.mvc.SimpleFormController">
  <property name="commandClass" value="business.domain.CmdTest" />
  <property name="formView" value="/WEB-INF/jsp/input.jsp" />
  <property name="successView" value="/WEB-INF/jsp/input.jsp" />
  <property name="validator" >
   <bean class="validator.CmdTestValidator"/>
  </property>
 </bean>
  
</beans>



【オブジェクト(CmdTest.java)】

ここで使用しているオブジェクト(POJO)です。

StrutsでいえばActionFormに当たるものです。

上記のSpringの設定はこのクラスに対してチェックをかけるように設定しています。


package business.domain;

public class CmdTest {

private boolean display = false;
private String message;

public boolean isDisplay() {
return display;
}
public void setDisplay(boolean display) {
this.display = display;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}


}




【View(input.jsp)】
値を入力してボタンを押すとエラーかどうかを表示してくれます。



<%@ page language="java" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"% >
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags " %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form " %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd ">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>入力テスト</title>
</head>
<body>
validatorControllerテスト<br>

<br>


<form:form method="post" >

<form:errors path="*" cssStyle="font-weight: bold; color: red;"></form:errors>
<br><br>

<form:checkbox path="display"/>

メッセージを表示します<br>

<form:input path="message"/>

<input type="submit" value="入力">
</form:form>

</body>
</html>



【表示画面】

http://localhost:8080/test/input.html



 
 Java Springの逆引きメモ
   ↓チェックボックスだけチェックして入力ボタンを押すと



  Java Springの逆引きメモ




【説明】


Viewを見てみてください。

目新しい、formタグが使われていますね。

これは、オブジェクト(ここではCmdTestクラス)と連動して値を入れてくれたりエラーメッセージを出力してくれるタグです。


とりあえず、それはメインではないので説明は別の記事に譲ります。



<Validatorクラス>

まず、Validatorクラスを見てください。

errors.rejectValueという処理をしています。

これがメインの妥当性チェックの処理です。


errors.rejectValue("message", "error.required", "メッセージは必須です");

 "message" ・・・ オブジェクトのプロパティ名(getter名)。

           JSPファイルでエラーメッセージを出力するときにも指定します。

 "error.required" ・・・ メッセージリソースからこの名称のメッセージを探してエラーメッセージにします。

              引数がある場合は、3番目の引数にObject[]型で指定します。

 "メッセージは必須です" ・・・ メッセージリソースから"error.required"が見つからないときにこの

                     メッセージを出力します。


このerrorsオブジェクトにはエラーとチェック対象オブジェクトを保持しています。

errorsオブジェクトが引き渡っていくことで最終的にはJSPに渡っていきます。



<errorsオブジェクトはどこからくるか?>

では、このerrorsオブジェクトはどこからValidatorに渡されるのでしょうか?

それは、Springの設定ファイルを見てみてください。


<bean id="validatorTestInputController" class="org.springframework.web.servlet.mvc.SimpleFormController">
<property name="commandClass" value="business.domain.CmdTest" />
<property name="formView" value="/WEB-INF/jsp/input.jsp" />
<property name="successView" value="/WEB-INF/jsp/input.jsp" />
<property name="validator" >
<bean class="validator.CmdTestValidator"/>
</property>
</bean>

SimpleFormControllerのプロパティとして設定されていますね。

はい。

そうです、SimpleformControllerがオブジェクトを作ってValidatorに渡してくるのです。

余談ですが、SimpleformControllerはBinderクラスというものを持っていて、

Binderがパラメタからオブジェクトを作っています。

Binderを変えることで独自のオブジェクトの作り方をさせることもできます。


これで画面表示の前までの処理はなんとなく分かったかと思います。



<JSPでの表示方法>

それでは、JSPでの表示方法を見てみましょう。


<form:errors path="*" cssStyle="font-weight: bold; color: red;"></form:errors>


簡単ですね。

Springで用意しているform:errors タグを使用するだけです。

ここでは pathを*にしていますが、errors.rejectValue()で指定した名称を指定できます!


 例:

 <form:errors path="message" cssStyle="font-weight: bold; color: red;">
  エラー起きてますよ。
 </form:errors>


中の「エラー起きてますよ。」は、エラーがおきているときだけ表示されます。


意外と便利でしょ?



他にも、spring:bindを使用する方法もありますが、formタグで十分でしょう。

興味があれば調べてみてください。





参考:

・トップ

・SpringModulesの機能について

・SpringMVCの機能について

・SpringMVCを使用してWEBを作るには? (基礎編)

・Springを使用するには?

・SpringでWEB作成するには?(基本的な作成例)

SpringMVCの基本を知る