一昨日の記事ではHello Worldしかやらなかったので続き。
郵便番号の妥当性チェックを、クライアント側とサーバー側で共通のjsを使って行う。
あくまでも最終的なデータの保証をするのはサーバー側で、
クライアント側でチェックを行うのは操作性アップのため
(サーバーといちいちやり取りしなくてもデータの検証が出来るとストレスが溜まらない)。
とはいっても、この件に関しては、通常はクライアントサイドでの検証が十分なら
サーバー側で弾かれるということはない(はず)。
但し、直リクエストされたりすると予期していない形のデータが送られてくることがあるので
サーバー側でのチェックは外せない。 ・・という思想で行く。
御託が長くなったが、以下、ソース。
/js/postalcodeutil.js
function isValidPostalCode( postalcode ){
return (postalcode.match(/^\d{3}-?\d{4}$/));
}
ただ正規表現にマッチするかどうかJavaScriptで調べるだけ。
これくらいのものならわざわざRhino使わずにJavaで書いたほうが楽だが、あくまでサンプルってことで。
index.jsp(入力画面)
POSTする前にJavaScriptで妥当性チェック。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/JavaScript" />
<script type="text/javascript" src="js/postalcodeutil.js"></script>
<script type="text/javascript">
<!--
function onSendButtonClick(){
if (isValidPostalCode(document.getElementById("PostalCodeEdit").value))
document.Form1.submit();
else
alert("NG");
}
// -->
</script>
</head>
<body><form name="Form1" method="POST" action="postalcode">
<table>
<tr>
<td>Postal Code:<td>
<td><input type="text" id="PostalCodeEdit" name="postalcode"
maxlength="8" size="8"/></td>
</tr>
<tr>
<td>Address:<td>
<td><input type="text" id="AddressEdit" name="address"
maxlength="40" size="40"/></td>
</tr>
<tr>
<td><td>
<td><input type="button" name="SendButton" value="send" onClick="onSendButtonClick()"></td>
</tr>
</table>
</form></body>
</html>
T2の@Formが便利。
Pageクラス
package examples.page;import javax.servlet.ServletContext;
import org.t2framework.commons.util.Logger;
import org.t2framework.t2.annotation.composite.GET;
import org.t2framework.t2.annotation.composite.POST;
import org.t2framework.t2.annotation.core.Default;
import org.t2framework.t2.annotation.core.Form;
import org.t2framework.t2.annotation.core.Page;
import org.t2framework.t2.navigation.Forward;
import org.t2framework.t2.spi.Navigation;import examples.dto.PostalcodeDTO;
import examples.util.PostalcodeUtil;@Page("/postalcode")
public class PostalCodePage {
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(PostalCodePage.class);@GET
@Default
public Navigation get(){
return Forward.to("/WEB-INF/pages/index.jsp");
}@POST
public Navigation post(final @Form PostalcodeDTO dto,
final ServletContext context) throws Exception{
PostalcodeUtil util = PostalcodeUtil.getInstance();
util.setJSPath(context.getRealPath("js/postalcodeutil.js"));if (util.isValidPostalCode(dto.getPostalcode())){
/*
* 正常時の処理をここに処理を書く
*/
} else {
/*
* エラー時の処理をここに処理を書く
*/
}
return Forward.to("/WEB-INF/pages/result.jsp");
}
}
DTOクラス(Formで送信されるData Transfer Object)
package examples.dto;import java.io.Serializable;
public class PostalcodeDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String postalcode;
private String address;
public void setPostalcode(String postalcode) {
this.postalcode = postalcode;
}
public String getPostalcode() {
return postalcode;
}
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
}
Rhinoを扱うクラス
package examples.util;import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;public class RhinoUtil {
private Context context;
private Scriptable scope;public RhinoUtil(String realpath) throws Exception{
context = Context.enter();
FileInputStream is = new FileInputStream(realpath);
BufferedReader reader =
new BufferedReader(new InputStreamReader(is, "UTF8"));scope = context.initStandardObjects();
context.evaluateReader(scope, reader, "<cmd>", 1, null);
reader.close();
is.close();
}
public Object execJSFunction(String functionname, Object functionArgs[])
throws Exception{
Object function = scope.get(functionname, scope);
if (!(function instanceof Function))
throw new RuntimeException("there is no function named " + functionname);return ((Function)function).call(context, scope, scope, functionArgs);
}
}
妥当性チェックのためのクラス
初回インスタンス化時のみjsを読み込むようにする。
package examples.util;import org.mozilla.javascript.Context;
import org.t2framework.commons.util.Logger;import examples.page.IndexPage;
public class PostalcodeUtil {
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(IndexPage.class);private static PostalcodeUtil instance = new PostalcodeUtil();
public static PostalcodeUtil getInstance() {
return instance;
}
private RhinoUtil rhinoutil = null;
public void setJSPath(String realpath) throws Exception{
if (rhinoutil != null)
return;
else
rhinoutil = new RhinoUtil(realpath);
}
public boolean isValidPostalCode(String postalcode) throws Exception{
Object functionArgs[] = {postalcode};
Object result = rhinoutil.execJSFunction("isValidPostalCode", functionArgs);
return Context.toBoolean(result);
}
}