2016-05-18 2 views
1

私は同様の質問があることを知っています。それらの例はあまりにも断片的で不明瞭です。@ ModelAttributeと抽象クラス

POSTを送信するページのフォームからエンティティを編集する必要があります。標準的なメソッドは、コントローラ内のメソッドで、パラメータを@ModelAttributeおよびバリデータで使用します。 1つのフォームが抽象クラスのいくつかのサブクラスを提供する場合、必要なフィールドの生成に問題はありませんが、コントローラに問題があります。

私が理解しているように、@ModelAttributeはこのように動作します。目的のオブジェクトクラスを初期化し、要求のパラメータのフィールドを収集します。もちろん、オブジェクトが抽象クラスの場合、初期化することはできません。したがって、フォームには初期化するサブクラスを示すフィールドがあります。次に、コードの平和が必要です。この属性はこの属性を読み、正しいサブクラスを初期化します。それは何でしょうか?私はConverter、PrepertyEditor、WebDataBinderについての断片的な例を見ましたが、すべてをまとめるのは難しいです。

So.次の階層があります。

@RequestMapping (Path = "/ persons/uid {personId}/edit", 
       method = RequestMethod.GET) 
public String editPerson (@PathVariable Integer personId, Model model) { 
    Person find = personDAO.read (personId); 
    model.addAttribute ("person", find); 
    return "editPerson"; 
} 

@RequestMapping (Path = "/ persons/uid {personId}/edit", 
       method = RequestMethod.POST) 
public String editPersonPost (@PathVariable Integer personId, 
     @Valid @ModelAttribute ("Person") Person person, 
     BindingResult result) { 
    if (result.hasErrors()) return "editPerson error = true?"; 
    personDAO.update (person); 
    return "redirect:/persons/uid" + personId + "saved = true?"; 
} 

とJSPはフォームであり:

public abstract class Person {role, name, email, password ...} 
public class Student extends Person {} 
public class Lecturer extends Person {} 

その中のコントローラおよび方法はあり

​​

また、コンバータは持っています書かれているが、それが必要であるかどうか、あるいは他のクラスを継承しているかどうかは疑問だ。

public class PersonConverter implements Converter <String, Person> { 

public Person convert (String personType) { 
    Person person = null; 
    switch (personType) { 
     case "Student": 
      person = new Student(); 
      break; 
     case "Lecturer": 
      person = new Lecturer(); 
      break; 
     default: 
      throw new IllegalArgumentException (
        "Unknown person type:" + personType); 
    } 
    return person; 
}} 
何かが欠落しているにもかかわらず、それはリクエストパラメータから person_typeを取り、コンバータにそれを与える方法であり、そしてそれは、コントローラを介したメソッドの結果を返しますConversionService

<bean class="org.springframework.context.support.ConversionServiceFactoryBean" 
    id="theConversionService"> 
    <property name="converters"> 
     <list> 
      <bean class="schedule.service.PersonConverter"></bean> 
     </list> 
    </property> 
</bean> 
<mvc:annotation-driven conversion-service="theConversionService" validator="validator"/> 

に登録されている

自動バインディングメカニズム

お願いします。

答えて

1

は、あなただけの

<input type="hidden" value="${person.role}" name="person_type" /> 

以下の要素がその名前の属性が、それはあなたのコントローラでモデルの属性と一致していることを

<input type="hidden" value="${person.role}" name="person" /> 

ので、人に変更されたことを確認する必要があり

public String editPersonPost (@PathVariable Integer personId, 
     @Valid @ModelAttribute ("person") Person person, 
     BindingResult result) 

これはどのように動作するのですか。

リクエストが受信され、Springがモデル属性を作成する必要がある場合、属性がすでに存在するかどうかを確認します。それが存在せず、一致する名前の要求パラメータがない場合、パラメータクラスのデフォルトのコンストラクタを使用して新しいオブジェクトを作成します。

存在し、引数タイプと一致する場合、要求パラメータをバインドします。互換性がないか、同じ名前のリクエストパラメータが利用可能な場合は、現在の値を必要な型に変換できるコンバータを見つけようとします。

変換が成功すると、要求パラメータが結果にバインドされます。例外

あなたの場合、person属性はStringとして送信されます。 SpringはそれをPersonに変換しようとします。バインドする前に適切なサブクラスに変換するためにPersonConverterを選択します