Struts2をやってみる (6) - フォームバリデーション (1) -

2013-09-19T00:00:00+00:00 Java Struts2

タイトル通り。ActionSupportなクラスにvalidateメソッドを定義する事で入力検証な機能を実装出来る。こいつの実体自体はValidateableインターフェースが作用している模様。

画面転移仕様

っていうような感じ

WEB-INF/jsp/index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <meta charset="utf-8" />
    <s:head />
  </head>
  <body>
    <s:form action="say">
      <s:textfield key="name" name="name" errorPosition="false" />
      <s:submit />
    </s:form>
    <s:fielderror key="name" theme="simple" />
  </body>
</html>

<s:textfield>にerrorPosition="false"をしているが、これを指定しなかった場合

というように<s:fielderror>でエラー表示の場所を指定したい場合にはこれを指定しないとフレームワークレベルで行われるエラー表示が出てしまう

んまぁあとは上記処理フローで書いているようにindex.actionでこれがレンダリングされてサブミットした際にsay.actionが発生、その際にバリデーションを行いエラー発生時にはこのビュー側に移動してエラーを表示するという事を行う

IndexAction.java

package sample.action;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class IndexAction extends ActionSupport {

    private static final long serialVersionUID = 1L;
    private String name = null;

    @Override
    public void validate() {
        if (StringUtils.isEmpty(getName())) {
            addFieldError("name", getText("name") + "を入力せよ");
        }
    }

    public String say() throws IOException {
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setContentType("text/plain); charset=utf-8");

        PrintWriter out = response.getWriter();
        out.print(name);
        out.flush();
        out.close();

        return NONE;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

addFieldErrorを使ってエラー情報を格納する。でgetTextっていうメソッドを使っているけど、src/main/resources/クラスパッケージ/クラス名.properties辺りに

name=名前

的なのを作っておけば取得出来るようになる模様

でsayの時点でバリデーションがずっこけたら、inputなresultに向かう模様なのでそれをもろもろ設定を行う

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>
    <constant name="struts.devMode" value="true" />

    <package name="sample" extends="struts-default" namespace="/sample">

        <action name="index" class="sample.action.IndexAction" method="input">
            <result name="input">/WEB-INF/jsp/index.jsp</result>
        </action>

        <action name="say" class="sample.action.IndexAction" method="say">
            <result name="input">/WEB-INF/jsp/index.jsp</result>
            <result name="success" />
        </action>

    </package>
</struts>

っていうような設定を行った場合には、index.actionからsay.actionへPOSTした場合にバリデーションがずっこけたらindex.jspが普通にforward(RequestDispatcher#forward)的な事が行われると思われるのだけど、これやるとリロード時にPOSTの状態が維持されたままなので所々問題になる場合もあるとは思う

そこでsay.actionからのinputなresultを<result name="input" type="redirectAction">を利用してアクションへリダイレクトされるようにした場合だとエラー情報をセッションなどに格納しない限りはバリデーションを行ったエラー情報が保持されない。でそれを解決する為にinterceptorを利用する事で可能らしいので上記の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>
    <constant name="struts.devMode" value="true" />

    <package name="sample" extends="struts-default" namespace="/sample">

        <action name="index" class="sample.action.IndexAction" method="input">
            <interceptor-ref name="store">
                <param name="operationMode">RETRIEVE</param>
            </interceptor-ref>
            <result name="input">/WEB-INF/jsp/index.jsp</result>
        </action>

        <action name="say" class="sample.action.IndexAction" method="say">
            <interceptor-ref name="store">
                <param name="operationMode">STORE</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack" />
            <result name="input" type="redirectAction">
                <param name="actionName">index</param>
                <param name="namespace">/sample</param>
            </result>
            <result name="success" />
        </action>

    </package>
</struts>

というようにstore interceptorを利用する事でメッセージングストアな機能を利用してエラーメッセージを保持出来るらしい

詳しくは http://struts.apache.org/release/2.1.x/docs/message-store-interceptor.html

終わり。というような感じでバリデーションな機能を利用する事が出来ると

色々方式があるようなのでバリデーションな機能に関してはまだ続くって事で

Struts2をやってみる (7) - フォームバリデーション (2) - HBaseのHFileをコマンドで読み取る方法