SpringMVC、MongoDBを使ってみたその4

今回はエラーチェックです。

エラーチェックの方法

エラーチェックはhibernateが用意しているものと自作をします。
やることは

  • サーバ名、OS、IPアドレス必須
  • IPアドレスIPアドレス(IPv4)の記法に一致しているか。(あんまり厳密にはみません)
  • インストールソフトのバージョンだけ入力されていないか。
hibernateの設定

hibernateのエラーチェックを使うので、pom.xmlに以下の記述を追加します。
追加後、pox.xml(プロジェクト)を右クリック→[Maven]→[Add Dependency]とします。

     <dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.0.0.GA</version>
     </dependency>
     <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>4.2.0.Final</version>
     </dependency>
     <dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.0</version>
エラーメッセージの設定
  1. ValidationMessages.propertiesをsrc/main/resources/org/hibernate/validator/ に追加します。
  2. hibernate-validator-XXX.jarの中身の中にあるプロパティファイルと同じディレクトリへ入れます。
  3. 自作のエラーチェックで使うためのメッセージを設定するプロパティファイル(messages.properties)をsrc/main/resources直下に配置します。
  4. プロパティファイルを使えるようにroot-context.xmlに設定を入れます。
   <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
          <property name="basename" value="classpath:messages" />
          <property name="cacheSeconds" value="0" />
     </bean>
NULLチェックの実装

単純な実装を行うときには、Beanクラス(正確にはBeanじゃないけど)に以下のような記述をします。
最大値や最小値などのチェックもできます。

public class EditPage {
     private String id ;
    
     /** サーバ名 */
     @NotEmpty
     private String serverName;
     /** IPアドレス */
     @NotEmpty
     private List<String> ips = new ArrayList<String>();
     /** OS */
     @NotEmpty
     private String os;
}
Validatorの実装

独自実装はValidatorインターフェースを実装します。
IPアドレスのエラーチェックは個別にエラーチェックを出したいので、以下のように個別で選択できるようにします。

rejectValueの第一引数がフィールド名となっています。
Listであるipsのi番目をエラーとする場合には、ips[i]と指定すればOKです。

          List<String> ips = page.getIps();
          int ipsSize = ips.size();

          for(int i = 0 ; i < ipsSize; i++){
               String ip = ips.get(i);
               if(StringUtils.hasText(ip) && !ip.matches(IP_ADDRESS_PATTERN)){
                    errors.rejectValue("ips["+i+"]", "error.nomatch", new Object[] {"IPアドレス"}, "");
               }
          }
画面JSPの実装

とすると、全フォームのエラーが表示されます。
Listは画面を表示させる時と同様にします。

<tableborder="1"]]>
<tr>
<td>サーバ名</td><td><form:inputpath="serverName"/><form:errorspath="serverName"/></td>
</tr>
<tr>
<td>IPアドレス</td>
<td>
<c:forEachitems="${editPage.ips}"var="ip"varStatus="status">
<form:inputpath="ips[${status.index}]"/><form:errorspath="ips[${status.index}]"></form:errors><br>
</c:forEach>
Controllerクラスの実装

Controllerクラスの第一引数の頭に@Validをつけて、エラーチェックします。
また、すべてのエラーチェックはBindingResultオブジェクトに入っているので、
bindingResult.hasErrors()がtrueの場合にはJSPへ戻るようにします。

     @RequestMapping(method = RequestMethod.POST)
     public String regist(@Valid EditPage page, BindingResult bindingResult, Model model ){
         
          // エラーチェック
          if(!isValid(page, bindingResult)){
               logger.debug(bindingResult.getObjectName());
               return "edit";
          }
     }

そうするとこんな感じです。多分あとはエラーのCSSとかつけるとかっこいいかも。