2012-08-23 411 views
1

我讀春天在行動,現在我在有關構建Web應用程序的章節,但我不能完全掌握一件事Spring MVC控制器 - 參數綁定

舉例來說,如果我們有方法是這樣的:

@RequestMapping(method=RequestMethod.GET, params="new") 
public String createSpitterProfile(Model model) { 
    model.addAttribute(new Spitter()); 
    return "spitters/edit"; 
} 

我們在這裏添加Spitter類模型的實例,因此它是通過這種形式

<div> 
<h2>Create a free Spitter account</h2> 

<sf:form method="POST" modelAttribute="spitter" 
    enctype="multipart/form-data">   
    <fieldset> 
    <table cellspacing="0"> 
    <tr> 
    <th><sf:label path="fullName">Full name:</sf:label></th> 
    <td><sf:input path="fullName" size="15" /><br/> 
    <sf:errors path="fullName" cssClass="error" /> 
    </td> 
    </tr> 
    <tr> 
    <th><sf:label path="username">Username:</sf:label></th> 
    <td><sf:input path="username" size="15" maxlength="15" /> 
     <small id="username_msg">No spaces, please.</small><br/> 
    <sf:errors path="username" cssClass="error" /> 

    </td> 
    </tr> 
    <tr> 
    <th><sf:label path="password">Password:</sf:label></th> 
    <td><sf:password path="password" size="30" 
      showPassword="true"/> 
    <small>6 characters or more (be tricky!)</small><br/> 
    <sf:errors path="password" cssClass="error" /> 
    </td> 
    </tr> 

    <tr> 
    <th><sf:label path="email">Email Address:</sf:label></th> 

    <td><sf:input path="email" size="30"/> 
    <small>In case you forget something</small><br/> 
    <sf:errors path="email" cssClass="error" /> 
    </td> 
    </tr> 
    <!--<start id="image_field"/>--> 
    <tr> 
    <th><label for="image">Profile image:</label></th> 
    <td><input name="image" type="file"/> 
    </tr> 
    <!--<end id="image_field"/>--> 
    <tr> 
    <th></th> 
    <td> 
    <sf:checkbox path="updateByEmail"/> 
    <sf:label path="updateByEmail" 
    >Send me email updates!</sf:label> 

    </td> 
    </tr> 
    <tr> 
    <th></th> 
    <td><input name="commit" type="submit" 
     value="I accept. Create my account." /></td> 
    </tr> 
    </table> 
</fieldset> 
</sf:form> 
</div> 

用戶輸入自己的數據後,這些輸入數據將被綁定到一些Spitter對象,將被

@RequestMapping(method=RequestMethod.POST) 
public String addSpitterFromForm(@Valid Spitter spitter, 
BindingResult bindingResult, 
@RequestParam(value="image", required=false) MultipartFile image) { 

    if(bindingResult.hasErrors()) { 
return "spitters/edit"; 
    } 

    spitterService.saveSpitter(spitter); 

    try { 
if(!image.isEmpty()) { 
    validateImage(image); 
    saveImage(spitter.getId() + ".jpg", image); 
} 
    } catch (ImageUploadException e) { 
bindingResult.reject(e.getMessage()); 
return "spitters/edit"; 
    } 

    return "redirect:/spitters/" + spitter.getUsername(); 
} 

我通過一些物體將被填充的模式進行處理,但我感興趣的是如何工作的一個因爲當頁面提供給用戶時,關於對象的信息就會丟失(或者我錯了)?

1.Does了在createSpitterProfile加入是相同的(相同的含義參考),如addSpitterFromFormSpitter對象或是在運行中創建彈簧第二個當所請求的數據而來的對象?

2,當用戶輸入的請求來到addSpitterFromForm,如何春季知道從表單中的信息應該被處理到Spitter對象,我知道有Spitter對象的方法簽名,但Spring如何知道數據應該填充這個對象屬性。

回答

2

您必須記住,客戶端Web瀏覽器從服務器獲取「普通的舊HTML」(這裏沒有魔術/隱藏的Java)。因此,Spring將模型對象編碼爲HTML,形式爲<form>輸入,廣播,選擇等。

用戶獲取正常的HTML網頁,填寫表單並按提交到POST或GET頁面回到網絡服務器。這就是Spring將其魔術「解碼」請求參數回到被綁定的對象(即Spitter)的地方。所以要回答Q1,沒有它的不一樣的對象,它的副本(甚至可能是有損拷貝)。對於Q2,當你要求Spring將一個請求綁定到一個對象時,它所做的只是試圖將請求參數名稱與對象上的設置器相匹配。它「知道」是因爲你在方法簽名中要求它。 Spring在決定如何處理方法簽名時會做一些奇特的事情,它的價值在於讀取它,因爲您提出參數的順序很重要。

+0

謝謝,這和我的實驗清除了我所有的疑惑。 – Andna