#freeze
[[FrontPage]]

#contents

2008/03/01からのアクセス回数 &counter;

* Spring-MVCのモデルでDate型を使いたい [#e05f4c02]

Spring-MVCのAbstractCommandControllerは、デフォルトではDate型と文字列の変換を
してくれません。

SpringマニュアルのValidation, Data-binding, the BeanWrapper, and PropertyEditorsには、
PropertyEditorRegistrarsを使ってコントローラのinitBinderメソッドでCustomEditorsを登録
する方法が紹介されています。

- カスタムプロパティエディタを定義
#pre{{
package com.foo.editors.spring;

public final class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {

    public void registerCustomEditors(PropertyEditorRegistry registry) {

        // it is expected that new PropertyEditor instances are created
        registry.registerCustomEditor(ExoticType.class, new ExoticTypeEditor());

        // you could register as many custom property editors as are required here...
    }
}
}}

- ControllerにinitBinderでカスタムプロパティエディタを登録する
#pre{{
public final class RegisterUserController extends SimpleFormController {

    private final PropertyEditorRegistrar customPropertyEditorRegistrar;

    public RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
        this.customPropertyEditorRegistrar = propertyEditorRegistrar;
    }

    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        this.customPropertyEditorRegistrar.registerCustomEditors(binder);
    }

    // other methods to do with registering a User
}
}}

しかし、この方法だとDate型をモデルに追加したときにすべてのControllerでinitBinderを定義
するしかありません。(継承を使えてばよいと言われるかもしれませんが、それでも余計な
Controllerクラスを作成する必要があります)

** Springらしい解決方法 [#kaac7f57]
ソースを辿っていくうちにSimpleFormControllerのpropertyEditorRegistrarsに登録してある
カスタムプロパティエディタのRegistrarを追加することで解決することが分かりました。

そこで、CustomPropertyEditorRegistrarクラスを以下のように作成しました。
#pre{{
package jp.co.pwv.utils;

import java.beans.PropertyEditor;
import java.util.Iterator;
import java.util.Map;

import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;

public class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar {
	Map<Class, PropertyEditor>	customEditors;
	public void registerCustomEditors(PropertyEditorRegistry registry) {
		Iterator<Class> itr = customEditors.keySet().iterator();
		while (itr.hasNext()) {
			Class key = itr.next();
			PropertyEditor editor = customEditors.get(key);
			registry.registerCustomEditor(key, editor);
		}
	}
	public Map<Class, PropertyEditor> getCustomEditors() {
		return customEditors;
	}
	public void setCustomEditors(Map<Class, PropertyEditor> customEditors) {
		this.customEditors = customEditors;
	}
}
}}

- Spring Bean定義ファイルでCustomPropertyEditorRegistrarを定義

#pre{{
	<bean id="dateFormat" class="java.text.SimpleDateFormat">
		<constructor-arg index="0" type="java.lang.String" value="yyyy-MM-dd" />
	</bean>
	
	<bean id="customEditorRegistrar" class="jp.co.pwv.utils.CustomPropertyEditorRegistrar">
	  <property name="customEditors">
	    <map>
	      <entry key="java.util.Date">
	        <bean class="org.springframework.beans.propertyeditors.CustomDateEditor">
				<constructor-arg index="0">
					<ref bean="dateFormat" />
				</constructor-arg>
				<constructor-arg  index="1" type="boolean" value="true"/>
	        </bean>
	      </entry>
	    </map>
	  </property>
	</bean>
}}

ここでは、Springの提供するCustomDateEditorを使ってDate型の文字列との変換するカスタムエディタを登録しました。

- フォームコントローラのBean定義にpropertyEditorRegistrarsを追加する
#pre{{
		<property name="propertyEditorRegistrars">
			<list>
				<ref bean="customEditorRegistrar"/>
			</list>
		</property>
}}

これでユーザがモデルで定義した型と文字列とを変換することができるようになります。

* コメント [#ea96dd56]
この記事は、

#vote(おもしろかった[22],そうでもない[2],わかりずらい[28])
#vote(おもしろかった[22],そうでもない[2],わかりずらい[29])

皆様のご意見、ご希望をお待ちしております。

#comment_kcaptcha

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc