通常,表單中的數據在提交之后可以通過Spring MVC的@RequestParam注解在控制器函數的參數列表中中提取出來,但是一旦表單數據過多的話,參數列表將會變得非常長,最好的解決方案是將表單中的數據封裝到一個自定義的對象中,這樣就可以直接用一個命令對象傳遞整個表單所包含的數據了。
關鍵字:#springBind宏
沒錯,這個宏是綁定的關鍵。首先我們需要開啟spring mvc在velocity模板中對宏的支持,這個需要做以下設置:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityViewResolver"
>
## ....
<property name="exposeSpringMacroHelpers">
<value>true</value>
</property>
</bean>
我們以一個簡單的登錄控制系統來說明一下綁定流程,假設我們要實現如下圖的一個界面:
從Spring MVC的角度來看,渲染出這個模板(假設此模板為login.vm)首先需要經過一個控制器的函數處理,假設這個函數名稱為autoBindLogin,那么這個函數在渲染模板時完成一件事,那就是告訴模板需要綁定的命令對象的實例是什么。
當然,我們首先得介紹一下命令對象所屬類的定義:
package com.lipan.DO;
public class AccountModel {
private String username;
private String password;
public void setUsername(String username){
this.username = username;
}
public void setPassword(String password){
this.password = password;
}
public String getUsername(){
return username;
}
public String getPassword(){
return password;
}
}
可以看到,這只是一個簡單的POJO類,純粹為了封裝數據產生的,其兩個成員變量分別對應login.vm中的兩個表單輸入。
回到剛才的問題,如何告訴表單綁定對象的實例呢?下面的代碼就是答案--我們生成一個給它,然后通過名稱約定(名稱相同)傳遞給模板。
//lipan : 傳入表單的對象
@RequestMapping(value="/autoBind", method={RequestMethod.GET})
public String autoBindLogin(Model model){
model.addAttribute("accountmodel", new AccountModel());
return "login";
}
這之后模板就可以用到傳遞進來的命令對象索引"$accountmodel"了,用法如下:
## login.vm
## author:lipan
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=GBK">
<title>data binding example</title>
</head>
<body>
<form method="post">
#springBind("accountmodel.username")
姓名:<input type="text" name="${status.expression}" value="$!status.value"/>
<font color="#FF0000">${status.errorMessage}</font><br/>
#springBind("accountmodel.password")
密碼:<input type="text" name="${status.expression}" value="$!status.value"/>
<font color="#FF0000">${status.errorMessage}</font><br/>
<input type="submit" name="Submit"/><br/>
</form>
</body>
</html>
一旦表單內容submit成功,這個實例可以傳到處理表單請求(此處是POST請求)的控制器中,由對應的函數處理,比如下面這個函數:
@RequestMapping(value="/autoBind", method={RequestMethod.POST})
public String autoBindResult(Model model,AccountModel am){
/*am.setPassword("lipantestpw");
am.setUsername("lipan");*/
model.addAttribute("accountmodel",am );
return "autoBindResult";
}
然后autoBindResult.vm就可以展現命令對象的具體內容了:
##autoBindResult.vm
##author:lipan
username: ${accountmodel.username}</br>
password: ${accountmodel.password}</br>
autoBindResult.vm的渲染結果如下: