Spring-MVCのValidationでドメインモデルのString型以外の属性を検証したい
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[FrontPage]]
#contents
2008/03/12からのアクセス回数 &counter;
* Spring-MVCのValidationでドメインモデルのString型以外の...
Formコントローラでエラーをチェックする場合、
- HTTPパラメータの値をcommandClassで指定されたオブジェク...
- オブジェクトの値のValidationを実施する
- HTTP要求を実行する
しかし、ドメインモデルのString型以外の属性に不適当な文字...
段階でエラーとなり、Validation機能が有効に働きません。
以下は、MemberクラスにInteger型のageを追加し、入力として...
を入力したときのエラー出力画面です。
#ref(validation_error1.jpg);
GenMVCプラグインで実行したいと考えているプログラミングは、
- ドメインモデルを定義する
- ドメインモデルからデータベースのテーブルを生成する
- CRUDを実行するDaoを生成する
- 編集、一覧表示のコントローラを生成する
- ビューのひな形を生成する
という一連の流れにおいて、ドメインモデルの属性の型にStrin...
致命的な問題です。
** 解決方法 [#meaf5664]
悩んだあげく以下のような方法で対応することにしました。
-- ドメインモデルに対応したコマンドオブジェクトを生成する
-- ドメインモデルとコマンドオブジェクト間の値の変換を行う...
*** ドメインモデルに対応したコマンドオブジェクトの生成 [#...
idを除くテーブル要素となる属性(テーブルのカラムに対応す...
それ以外をそのままの型と持ち、それらのアクセスメソッドを...
Cart問題のLineItemを定義しますと、
#pre{{
public class LineItem {
private Integer id;
private Integer quantity = new Integer(1);
private Integer productId;
private Product product;
private Integer orderId;
-- アクセスメソッドは省略
}
}}
から以下のようなコマンドオブジェクトが生成されます。
#pre{{
package example.cart.command;
public class LineItemCommand {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
private String orderId;
public String getOrderId () {
return orderId;
}
public void setOrderId (String orderId) {
this.orderId = orderId;
}
-- productId, quantity は、省略
private example.cart.domain.Product product;
public example.cart.domain.Product getProduct () {
return product;
}
public void setProduct (example.cart.domain.Product prod...
this.product = product;
}
}
}}
*** ドメインモデルとコマンドオブジェクト間の変換関数 [#g4...
先ほどのLineItemの編集を行うEditLineItemControllerを見て...
#pre{{
protected void bind(Object target, Object source) throw...
CustomDataBinder binder = new CustomDataBinder(target, ...
this.prepareBinder(binder);
binder.bind();
}
protected Object commandToDomain(Object source) throws E...
Object object = new LineItem();
bind(object, source);
return (object);
}
protected Object domainToCommand(Object source) throws E...
Object object = new LineItemCommand();
bind(object, source);
return (object);
}
}}
-- bindメソッドでsourceからtargetに値をbind(変換してセッ...
-- commandToDomainでコマンドオブジェクトからドメインモデ...
-- domainToCommandでドメインモデルからコマンドオブジェク...
*** CustomDataBinderの処理 [#h0673ec5]
このように簡単にコマンドオブジェクトとドメインモデルの属...
ServletRequestDataBinderとCustomDataBinderのおかげです。
CustomDataBinderでは、
-- コピー元のオブジェクトの属性からテーブルにマッピングし...
-- それ以外の属性はそのまま値をコピーします
以下にCustomDataBinderのソースを示します。
#pre{{
package jp.co.pwv.utils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jp.co.pwv.utils.DbHelper;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.bind.ServletRequestDataBin...
public class CustomDataBinder extends ServletRequestDataB...
DbHelper helper;
Map valueMap = new HashMap();
private void setUpValueMap(Object source) {
List propList = helper.getPropList();
for (int i = 0; i < propList.size(); i++) {
PropertyDescriptor objProp = (PropertyDescriptor)propL...
String propName = objProp.getName().toUpperCase();
Class propType = objProp.getPropertyType();
Method getMethod = objProp.getReadMethod();
Object propValue = null;
try {
propValue = getMethod.invoke(source, null);
}
catch (Exception e) {
propValue = null;
}
if (propName.equals("CLASS")) // オブジェクト自身を除く
continue;
if (propValue != null)
if (Integer.class.equals(propType) ||
Double.class.equals(propType) ||
Boolean.class.equals(propType) ||
String.class.equals(propType) ||
Date.class.equals(propType) ||
java.util.Date.class.equals(propType) ||
Timestamp.class.equals(propType)) {
valueMap.put(objProp.getName(), propValue.toString());
}
else {
valueMap.put(objProp.getName(), propValue);
}
}
}
public CustomDataBinder(Object target, Object source) {
super(target);
helper = new DbHelper(source.getClass());
setUpValueMap(source);
}
public void bind() throws Exception {
MutablePropertyValues mpvs = new MutablePropertyValues();
mpvs.addPropertyValues(valueMap);
super.doBind(mpvs);
}
}
}}
** 動作の確認 [#bf3f71b8]
validation.xmlのmemberCommandのフォームのageのチェックをr...
#pre{{
<form name="memberCommand">
<field property="address" depends="required">
<arg0 key="member.address" />
</field>
<field property="age" depends="required,integer">
<arg0 key="member.age" />
</field>
<field property="name" depends="required">
<arg0 key="member.name" />
</field>
</form>
}}
mavenでパッケージ、jettyを起動します。
#pre{{
$ mvn package
$ mvn jetty:run
}}
正常に動作し、"Member age must be an integer"のメッセージ...
#ref(validation_ok.jpg);
* コメント [#oace2596]
この記事は、
#vote(おもしろかった[0],そうでもない[0],わかりずらい[5])
皆様のご意見、ご希望をお待ちしております。
#comment_kcaptcha
終了行:
[[FrontPage]]
#contents
2008/03/12からのアクセス回数 &counter;
* Spring-MVCのValidationでドメインモデルのString型以外の...
Formコントローラでエラーをチェックする場合、
- HTTPパラメータの値をcommandClassで指定されたオブジェク...
- オブジェクトの値のValidationを実施する
- HTTP要求を実行する
しかし、ドメインモデルのString型以外の属性に不適当な文字...
段階でエラーとなり、Validation機能が有効に働きません。
以下は、MemberクラスにInteger型のageを追加し、入力として...
を入力したときのエラー出力画面です。
#ref(validation_error1.jpg);
GenMVCプラグインで実行したいと考えているプログラミングは、
- ドメインモデルを定義する
- ドメインモデルからデータベースのテーブルを生成する
- CRUDを実行するDaoを生成する
- 編集、一覧表示のコントローラを生成する
- ビューのひな形を生成する
という一連の流れにおいて、ドメインモデルの属性の型にStrin...
致命的な問題です。
** 解決方法 [#meaf5664]
悩んだあげく以下のような方法で対応することにしました。
-- ドメインモデルに対応したコマンドオブジェクトを生成する
-- ドメインモデルとコマンドオブジェクト間の値の変換を行う...
*** ドメインモデルに対応したコマンドオブジェクトの生成 [#...
idを除くテーブル要素となる属性(テーブルのカラムに対応す...
それ以外をそのままの型と持ち、それらのアクセスメソッドを...
Cart問題のLineItemを定義しますと、
#pre{{
public class LineItem {
private Integer id;
private Integer quantity = new Integer(1);
private Integer productId;
private Product product;
private Integer orderId;
-- アクセスメソッドは省略
}
}}
から以下のようなコマンドオブジェクトが生成されます。
#pre{{
package example.cart.command;
public class LineItemCommand {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
private String orderId;
public String getOrderId () {
return orderId;
}
public void setOrderId (String orderId) {
this.orderId = orderId;
}
-- productId, quantity は、省略
private example.cart.domain.Product product;
public example.cart.domain.Product getProduct () {
return product;
}
public void setProduct (example.cart.domain.Product prod...
this.product = product;
}
}
}}
*** ドメインモデルとコマンドオブジェクト間の変換関数 [#g4...
先ほどのLineItemの編集を行うEditLineItemControllerを見て...
#pre{{
protected void bind(Object target, Object source) throw...
CustomDataBinder binder = new CustomDataBinder(target, ...
this.prepareBinder(binder);
binder.bind();
}
protected Object commandToDomain(Object source) throws E...
Object object = new LineItem();
bind(object, source);
return (object);
}
protected Object domainToCommand(Object source) throws E...
Object object = new LineItemCommand();
bind(object, source);
return (object);
}
}}
-- bindメソッドでsourceからtargetに値をbind(変換してセッ...
-- commandToDomainでコマンドオブジェクトからドメインモデ...
-- domainToCommandでドメインモデルからコマンドオブジェク...
*** CustomDataBinderの処理 [#h0673ec5]
このように簡単にコマンドオブジェクトとドメインモデルの属...
ServletRequestDataBinderとCustomDataBinderのおかげです。
CustomDataBinderでは、
-- コピー元のオブジェクトの属性からテーブルにマッピングし...
-- それ以外の属性はそのまま値をコピーします
以下にCustomDataBinderのソースを示します。
#pre{{
package jp.co.pwv.utils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jp.co.pwv.utils.DbHelper;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.bind.ServletRequestDataBin...
public class CustomDataBinder extends ServletRequestDataB...
DbHelper helper;
Map valueMap = new HashMap();
private void setUpValueMap(Object source) {
List propList = helper.getPropList();
for (int i = 0; i < propList.size(); i++) {
PropertyDescriptor objProp = (PropertyDescriptor)propL...
String propName = objProp.getName().toUpperCase();
Class propType = objProp.getPropertyType();
Method getMethod = objProp.getReadMethod();
Object propValue = null;
try {
propValue = getMethod.invoke(source, null);
}
catch (Exception e) {
propValue = null;
}
if (propName.equals("CLASS")) // オブジェクト自身を除く
continue;
if (propValue != null)
if (Integer.class.equals(propType) ||
Double.class.equals(propType) ||
Boolean.class.equals(propType) ||
String.class.equals(propType) ||
Date.class.equals(propType) ||
java.util.Date.class.equals(propType) ||
Timestamp.class.equals(propType)) {
valueMap.put(objProp.getName(), propValue.toString());
}
else {
valueMap.put(objProp.getName(), propValue);
}
}
}
public CustomDataBinder(Object target, Object source) {
super(target);
helper = new DbHelper(source.getClass());
setUpValueMap(source);
}
public void bind() throws Exception {
MutablePropertyValues mpvs = new MutablePropertyValues();
mpvs.addPropertyValues(valueMap);
super.doBind(mpvs);
}
}
}}
** 動作の確認 [#bf3f71b8]
validation.xmlのmemberCommandのフォームのageのチェックをr...
#pre{{
<form name="memberCommand">
<field property="address" depends="required">
<arg0 key="member.address" />
</field>
<field property="age" depends="required,integer">
<arg0 key="member.age" />
</field>
<field property="name" depends="required">
<arg0 key="member.name" />
</field>
</form>
}}
mavenでパッケージ、jettyを起動します。
#pre{{
$ mvn package
$ mvn jetty:run
}}
正常に動作し、"Member age must be an integer"のメッセージ...
#ref(validation_ok.jpg);
* コメント [#oace2596]
この記事は、
#vote(おもしろかった[0],そうでもない[0],わかりずらい[5])
皆様のご意見、ご希望をお待ちしております。
#comment_kcaptcha
ページ名:
SmartDoc