2016-05-18 222 views
1

我知道有類似的問題。其中給出的例子太零星而且不清楚。@Model屬性和抽象類

我需要通過發送POST的頁面上的窗體來編輯實體。標準方法是控制器在@ModelAttribute和驗證器中使用參數的方法。如果一個表單爲抽象類的某個子類提供服務,那麼在生成必需字段時就沒有問題,但控制器中存在問題。

據我所知,@ModelAttribute這樣工作:它初始化所需的對象類,然後收集他的請求參數字段。當然,如果對象是一個抽象類,它不能被初始化。因此,該表單有一個字段,用於指示要初始化的子類。接下來,我們需要和平的代碼,它會讀取這個屬性並初始化正確的子類。它應該是什麼?我看到關於Converter,PrepertyEditor,WebDataBinder的部分示例,但很難將所有內容放在一起。

所以。有以下層次:

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

有一個控制器和方法吧:

@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 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; 
}} 

這與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"/> 

然而,缺少的東西,那就是將person_type從請求參數並給它轉換器的方法,它將返回該方法通過控制器的結果自動綁定機制。

請幫助我。

回答

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需要創建模型屬性時,它會檢查屬性是否已經存在。如果它不存在,並且沒有匹配名稱的請求參數,則它使用參數類的默認構造函數創建一個新對象。

如果它存在並與參數類型相匹配,則繼續綁定請求參數。如果它不兼容或者具有相同名稱的請求參數可用,它會嘗試查找能夠將當前值轉換爲所需類型的轉換器

如果轉換成功,它將請求參數綁定到結果,否則它會拋出一個異常

在你的情況下,人物屬性作爲字符串發送。 Spring將嘗試將其轉換爲Person。它會在綁定之前選擇您的PersonConverter進行轉換爲適當的子類