2011-12-04 12 views
7

私はリッチコンテンツを表示するためにレンダリングできるテキストの部分である多数の '要素'を特徴とするドメインモデルを持っています。 HTMLテキスト、テキスタイルテキスト、Flashオブジェクトなどがあります。これらの要素の基本的な機能はAbstractElementにカプセル化されており、実装はHTMLElement,FlashElementなどとなっています。したがってモデルには、持つことができるすべての要素を含むList<AbstractElement>があります。ジェネリックの自動募集リスト

モデルを編集するときに、ユーザーがフォームをサブミットするときに、ユーザーが要素を動的に追加して保存できるようにします。それでは、私が持っていることは、次の形式になり、いくつかのJavaScriptと動的に拡張可能な形式である:

<form action=...> 
    <!-- Other attributes --> 
    <textarea name="object.elements[0].content"/> 
    <textarea name="object.elements[1].content"/> 
    <!-- Some elements are based on text, others on files --> 
    <input type="hidden" name="object.elements[2].file" value="somevalue"/> 
    <textarea name="object.elements[3].content"/> 
    <!-- Submit button --> 
</form> 

フォームの送信時にこれがうまくいきません。なぜ、提出されたとき、Springはリスト内の必須要素をインスタンス化しようとしますか?要素のリストには抽象型のAbstractElementのオブジェクトが含まれているため、Springは新しい要素をインスタンス化できません。

Springが適切なタイプの要素をインスタンス化する方法は?フォームに型情報を追加して、ModelAttributeでそれを行うことができますか?それはどのように機能しますか?これを自動的に行うモデルでできることはありますか?

答えて

1

私は、生のフォームデータを解析して要素のリストを構築するModelAttributeを実装することでこれを解決しました。生のフォームデータを解析するには、HttpServletRequestオブジェクトを使用し、パラメータマップをループし、必要なオブジェクトを手作業で作成するだけで使用できます。ヘルパー関数に入れると再利用できますが、私が使用するすべてのコントローラにModelAttributeが必要です。

これは理想的な解決策ではありません。

1

リクエストパラメータを受け取り、正しいクラスインスタンスに変換してコレクションに追加できる顧客プロパティエディタを1つ(または複数)作成する必要があるようです。

Springは、データバインダーに登録されたPropertyEditorインスタンスを使用して、リクエストパラメータをバインドします。 PropertyEditorsのデフォルトセットが正しいタイプを判別できない場合は、独自のエディターを登録してロジックを処理できます。

プロセスは、このリンクで春のドキュメントに記述されています

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html

具体的には、顧客のプロパティエディタを登録する方法についてはセクション5.4.2.1を参照してください。

コントローラのinitBinder()メソッド(@InitBinderアノテーションで特定)のWebDataBinderクラスのregisterCustomEditor()メソッドを使用して、プロパティエディタを登録できます。

+0

Javaオブジェクトに単一のテキスト値(日付形式など)を処理するPropertyEditorはありませんか?リクエストパラメータを追加するにはどうすればよいですか? – DCKing

+0

あなたの質問から、エンドユーザーがHTMLフォームにさまざまなテキストエリアを入力して送信していたようです。投稿時には、各テキストエリアの内容に基づいて、インスタンス化するオブジェクトの正しいタイプを何らかの形で決定したいと思っていました。 PropertyEditorを使用すると、文字列と任意のタイプのオブジェクトの間で変換を行うことができますので、それがうまくいくと思います。私がフォームを正しく理解していない場合は、より詳細な情報を提供してください。 – khill

+0

サンプルフォームでわかるように、要素には 'content'属性が付いていることは確かではありません。代わりに 'file'属性を持つことができます。 PropertyEditorはそれを聞くことができませんでした。さらに、異なるタイプのテキストベースのコンテンツは、文字列の内容に基づいて必要に応じて区別することができない。 – DCKing

0

具体的なオブジェクトを返すModelAttributeメソッドを作成して、formObjectをインスタンス化することができます。例:

@ModelAttribute("bindingObj") 
public AbstractObject initElementList() { 
    AbstractObject obj = new ConcreteObject(); 
    obj.setElements(new ArrayList<ConcreteElement>); 
    return obj; 
} 

@RequestMapping(...) 
public ModelAndView requestHandler(@ModelAttribute("bindingObj") AbstractObject) { 
    .... 
} 

春は最初にinitElementListを呼び出し、結果を内部modelMapに追加します。そして、この値でrequestHandlerを呼び出します。

このアプローチの欠点は、あなたがまだ具体的なクラスへの参照を持つことになるということです。しかし、ベース・コントローラから派生したサブクラスがあれば、それは役に立ちます。

+0

質問には言及しませんでしたが、ソリューションがコントローラ間で簡単に再利用できることは有益です。要素のリストを持つモデルが増えています。これは1つのコントローラにとって非常に特有のものですね? – DCKing

+0

カスタムPropertyEditorはオプションですが、エディタのリスト要素の具体的な型をどのように解決できるかわかりません。各コントローラはどのリスト要素をバインドする必要があるかを知っているため、おそらくコントローラーがこれに最適な場所です。 – praveenj

関連する問題