使用Spring的表單標籤庫css
從2.0版本開始,若是使用JSP和Spring Web MVC的話,Spring提供了一套支持數據綁定的標籤集合,用於處理表單元素。每一個標籤所支持的屬性集合和與其對應的HTML標籤相同,這就讓這些標籤看起來很熟悉,並且用起來很直觀。 由這些標籤庫生成的HTML頁面符合HTML 4.01/XHTML 1.0標準。java
與其它表單/輸入標籤庫不一樣,Spring的表單標籤庫與Spring Web MVC集成在一塊兒, 使標籤可使用命令對象(command object)和你的控制器處理的參考數據(reference data)。 就像下面這些例子展現的同樣,表單標籤讓JSP更易於開發、閱讀和維護。spring
讓咱們進入表單標籤的領域,並經過一個例子研究每一個標籤如何使用。 當某些標籤須要更進一步的解釋時,咱們已經把所生成的HTML片斷也一塊兒列了進來。服務器
1. 配置dom
Spring的表單標籤庫包含在spring.jar中。 這個庫的描述符(descriptor)叫作spring-form.tld。jsp
要使用這個庫中的標籤,在JSP頁面的開頭加入下面聲明:ui
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>this
在上面的聲明中,form就是爲想要使用的這個庫中的標籤所肯定的標籤命名前綴。spa
2. form標籤rest
這個標籤會生成一個HTML的「form」標籤,同時爲內部標籤的綁定暴露了一個綁定路徑(binding path)。 它把命令對象(command object)放在PageContext中,這樣內部的標籤就能夠訪問這個命令對象了。 這個庫中的其餘標籤都是form標籤的嵌套標籤。
假設咱們有一個叫作User的領域對象,它是一個JavaBean,擁有諸如firstName和lastName這樣的屬性。 咱們將把它看成返回form.jsp的表單控制器的表單支持對象(form backing object)。下面是一個form.jsp可能的樣子的例子:
<form:form>
<table>
<tr>
<td>First Name:</td>
<td><form:input path="firstName" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save Changes" />
</td>
</tr>
</table>
</form:form>
上面firstName和lastName的值是從由頁面控制器放置在PageContext中的命令對象中獲得的。 請繼續讀下去來看幾個關於如何使用form標籤的內部標籤的例子。
生成的HTML看起來就是一個標準的form:
<form method="POST">
<table>
<tr>
<td>First Name:</td>
<td><input name="firstName" type="text" value="Harry"/></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input name="lastName" type="text" value="Potter"/></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save Changes" />
</td>
</tr>
</table>
</form>
上面的JSP有一個預設前提,就是表單支持對象(form backing)的變量名是「command」。 若是你將這個表單支持對象用其餘名稱加以定義(這可算是一種最佳實踐),你就能夠將這個命名變量綁定到表單上,以下例所示:
<form:form commandName="user">
<table>
<tr>
<td>First Name:</td>
<td><form:input path="firstName" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save Changes" />
</td>
</tr>
</table>
</form:form>
3. input標籤
這個標籤生成一個「text」類型的HTML「input」標籤。 關於這個標籤的示例,很簡單在這裏不用贅述。
4. checkbox標籤
這個標籤生成一個「checkbox」類型的HTML「input」標籤。
讓咱們假設咱們的User有好比新聞訂閱和其餘一組業餘愛好這樣的偏好。 下面就是一個Preferences類的例子:
public class Preferences {
private boolean receiveNewsletter;
private String[] interests;
private String favouriteWord;
public boolean isReceiveNewsletter() {
return receiveNewsletter;
}
public void setReceiveNewsletter(boolean receiveNewsletter) {
this.receiveNewsletter = receiveNewsletter;
}
public String[] getInterests() {
return interests;
}
public void setInterests(String[] interests) {
this.interests = interests;
}
public String getFavouriteWord() {
return favouriteWord;
}
public void setFavouriteWord(String favouriteWord) {
this.favouriteWord = favouriteWord;
}
}
form.jsp以下:
<form:form>
<table>
<tr>
<td>Subscribe to newsletter?:</td>
<%-- Approach 1: Property is of type java.lang.Boolean --%>
<td><form:checkbox path="preferences.receiveNewsletter"/></td>
</tr>
<tr>
<td>Interests:</td>
<td>
<%-- Approach 2: Property is of an array or of type java.util.Collection --%>
Quidditch: <form:checkbox path="preferences.interests" value="Quidditch"/>
Herbology: <form:checkbox path="preferences.interests" value="Herbology"/>
Defence Against the Dark Arts: <form:checkbox path="preferences.interests"
value="Defence Against the Dark Arts"/>
</td>
</tr>
<tr>
<td>Favourite Word:</td>
<td>
<%-- Approach 3: Property is of type java.lang.Object --%>
Magic: <form:checkbox path="preferences.favouriteWord" value="Magic"/>
</td>
</tr>
</table>
</form:form>
有三種checkbox標籤的使用方法知足你對checkbox的需求。
· 第一種用法:若綁定值是java.lang.Boolean類型,則值爲true時,input(checkbox)就標記爲選中。其value屬性對應於setValue(Object)值的屬性的解析值。
· 第二種用法:若綁定值是array或java.util.Collection類型,則當設定的setValue(Object)值出如今綁定的Collection中時,input(checkbox)就標記爲選中。
· 第三種用法:若綁定值爲其餘類型,則當設定的setValue(Object)與其綁定值相等時,input(checkbox)才標記爲選中。
注意,無論使用哪一種方法,生成的HTML結構都是相同的。下面是包含一些checkbox的HTML片斷:
<tr>
<td>Interests:</td>
<td>
Quidditch: <input name="preferences.interests" type="spring.framework.eckbox" value="Quidditch"/>
<input type="hidden" value="1" name="_preferences.interests"/>
Herbology: <input name="preferences.interests" type="spring.framework.eckbox" value="Herbology"/>
<input type="hidden" value="1" name="_preferences.interests"/>
Defence Against the Dark Arts: <input name="preferences.interests" type="spring.framework.eckbox"
value="Defence Against the Dark Arts"/>
<input type="hidden" value="1" name="_preferences.interests"/>
</td>
</tr>
也許沒有注意到的是在每一個checkbox背後還隱藏了其餘字段(field)。當一個HTML頁面中的checkbox沒有被選中時,它的值不會在表單提交時做爲HTTP請求參數的一部分發送到服務器端, 所以咱們須要給這個HTML的奇怪動做想出一個變通方案,來讓Spring的表單數據綁定能夠工做。 checkbox標籤遵循了Spring現有的慣例,就是對於每一個checkbox都包含了一個下劃線("_"),再跟上一個隱藏參數。 這樣一來,就至關於告訴Spring「 這個checkbox在表單中是可見的,而且但願表單數據將要被綁定到的對象可以反映出任意的checkbox的狀態」。
5. checkboxes標籤
這個標籤生成多個「checkbox」類型的HTML「input」標籤。
這一節創建在上一節checkbox標籤的例子之上。 有時傾向於並不在JSP頁面中列出所有可能的業餘愛好,而是想在運行時提供一個可用選項的清單,並把它傳遞給相應標籤。這就是checkboxes標籤的目標。 傳入一個Array、List,或者Map, 並把可用選項包含在「items」屬性中。典型的狀況是,這個綁定的屬性是一個集合,這樣它才能持有用戶選擇的多個值。 下面是使用了這個標籤的JSP的一個例子:
<form:form>
<table>
<tr>
<td>Interests:</td>
<td>
<%-- Property is of an array or of type java.util.Collection --%>
<form:checkboxes path="preferences.interests" items="${interestList}"/>
</td>
</tr>
</table>
</form:form>
這個例子假定了「interestList」是一個List,做爲模型屬性它包含了用於被選擇的字符串的值。而在使用一個Map的狀況下,map條目的鍵被用做值,map條目的值被用做顯示的文本標記。 也可使用一個定製的對象,提供「itemValue」屬性存放值,「itemLabel」屬性存放文本標記。
6. radiobutton標籤
這個標籤生成一個「radio」類型的HTML「input」標籤。
一個典型用法是把多個標籤實例綁定到同一屬性上,但它們有不一樣的值。
<tr>
<td>Sex:</td>
<td>Male: <form:radiobutton path="sex" value="M"/> <br/>
Female: <form:radiobutton path="sex" value="F"/> </td>
</tr>
7. radiobuttons標籤
這個標籤生成多個「radio」類型的HTML「input」標籤。
正像上面提到的checkboxes標籤,你可能但願傳入一個運行時的變量做爲可用的選項。 這種用法下就須要使用radiobuttons標籤。 傳入一個Array、List,或者Map, 並把可用選項包含在「items」屬性中。在使用Map的狀況下,map條目的鍵被用做值, map條目的值被用做顯示的文本標記。也可使用一個定製的對象,提供「itemValue」屬性存放值,「itemLabel」屬性存放文本標記。
<tr>
<td>Sex:</td>
<td><form:radiobuttons path="sex" items="${sexOptions}"/></td>
</tr>
8. password標籤
這個標籤生成一個「password」類型的HTML「input」標籤,並賦以綁定的值。
<tr>
<td>Password:</td>
<td>
<form:password path="password" />
</td>
</tr>
請注意默認狀況下,口令的值不會被顯示出來。 若是必定要顯示口令的值,就把「showPassword」屬性的值置爲true。
<tr>
<td>Password:</td>
<td>
<form:password path="password" value="^76525bvHGq" showPassword="true" />
</td>
</tr>
9. select標籤
這個標籤生成一個HTML「select」元素。它支持被選中的選項的數據綁定,也支持使用嵌套的option和options標籤。
咱們假設有一個User擁有多項專長。
<tr>
<td>Skills:</td>
<td><form:select path="skills" items="${skills}"/></td>
</tr>
若是這個User的專長是草藥學,那麼「Skills」這一行的HTML源代碼就以下所示:
<tr>
<td>Skills:</td>
<td><select name="skills" multiple="true">
<option value="Potions">Potions</option>
<option value="Herbology" selected="selected">Herbology</option>
<option value="Quidditch">Quidditch</option></select>
</td>
</tr>
10. option標籤
這個標籤生成一個HTML的「option」。根據綁定的值,它會恰當的設置「selected」屬性。
<tr>
<td>House:</td>
<td>
<form:select path="house">
<form:option value="Gryffindor"/>
<form:option value="Hufflepuff"/>
<form:option value="Ravenclaw"/>
<form:option value="Slytherin"/>
</form:select>
</td>
</tr>
若是這個User的宿舍在Gryffindor(Gryffindor是哈利·波特在Hogwarts的宿舍——譯者注), 那麼「House」這一行的HTML源代碼就以下所示:
<tr>
<td>House:</td>
<td>
<select name="house">
<option value="Gryffindor" selected="selected">Gryffindor</option>
<option value="Hufflepuff">Hufflepuff</option>
<option value="Ravenclaw">Ravenclaw</option>
<option value="Slytherin">Slytherin</option>
</select>
</td>
</tr>
11. options標籤
這個標籤生成一個HTML的「option」標籤的列表。根據綁定的值,它會恰當的設置「selected」屬性。
<tr>
<td>Country:</td>
<td>
<form:select path="country">
<form:option value="-" label="--Please Select"/>
<form:options items="${countryList}" itemValue="code" itemLabel="name"/>
</form:select>
</td>
</tr>
若是這個User生活在英國,那麼「Country」這一行的HTML源代碼就以下所示:
<tr>
<td>Country:</td>
<td>
<select name="country">
<option value="-">--Please Select</option>
<option value="AT">Austria</option>
<option value="UK" selected="selected">United Kingdom</option>
<option value="US">United States</option>
</select>
</td>
</tr>
上面的例子展現告終合使用option標籤和options標籤產生相同的標準HTML, 也讓你在JSP中顯式的指定一個值只用於顯示目的(在它所處的位置),例如例子中的默認字符串:「--Please Select」。
12. textarea標籤
這個標籤生成一個HTML的「textarea」。
<tr>
<td>Notes:</td>
<td><form:textarea path="notes" rows="3" cols="20" /></td>
<td><form:errors path="notes" /></td>
</tr>
13. hidden標籤
這個標籤使用綁定的值生成類型爲「hidden」的HTML「input」標籤。 在生成的HTML代碼中,input標籤的值和表單支持對象相應屬性的值保持一致。 若是要提交一個未綁定的值,就只能使用類型爲「hidden」的HTML input標籤了。
<form:hidden path="house" />
若是咱們選擇以隱藏形式提交「house」的值,HTML代碼將以下所示:
<input name="house" type="hidden" value="Gryffindor"/>
14. errors標籤
這個標籤經過一個HTML「span」標籤展示字段的錯誤。它提供了訪問由你的控制器或者與你的控制器關聯的任何驗證器產生的錯誤的途徑。
假設咱們想要在表單提交時顯示全部與firstName和lastName字段有關的錯誤。咱們爲User類的實例編寫了名爲UserValidator的驗證器。
public class UserValidator implements Validator {
public boolean supports(Class candidate) {
return User.class.isAssignableFrom(candidate);
}
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "required", "Field is required.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "lastName", "required", "Field is required.");
}
}
form.jsp將以下所示:
<form:form>
<table>
<tr>
<td>First Name:</td>
<td><form:input path="firstName" /></td>
<%-- Show errors for firstName field --%>
<td><form:errors path="firstName" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName" /></td>
<%-- Show errors for lastName field --%>
<td><form:errors path="lastName" /></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Save Changes" />
</td>
</tr>
</table>
</form:form>
若是咱們提交的表單的firstName和lastName字段均爲空值, HTML頁面將以下所示:
<form method="POST">
<table>
<tr>
<td>First Name:</td>
<td><input name="firstName" type="text" value=""/></td>
<%-- Associated errors to firstName field displayed --%>
<td><span name="firstName.errors">Field is required.</span></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input name="lastName" type="text" value=""/></td>
<%-- Associated errors to lastName field displayed --%>
<td><span name="lastName.errors">Field is required.</span></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Save Changes" />
</td>
</tr>
</table>
</form>
若是咱們想要顯示一個指定頁面上的全部錯誤清單,又該如何呢? 下面的例子展現了errors標籤也支持一些基本的通配符功能。
· path="*":顯示全部錯誤
· path="lastName*":顯示全部與lastName字段有關的錯誤
下面的例子將會在頁面頭部顯示一個錯誤清單,後面則在每一個字段旁邊顯示該字段特有的錯誤:
<form:form>
<form:errors path="*" cssClass="errorBox" />
<table>
<tr>
<td>First Name:</td>
<td><form:input path="firstName" /></td>
<td><form:errors path="firstName" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName" /></td>
<td><form:errors path="lastName" /></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Save Changes" />
</td>
</tr>
</table>
</form:form>
HTML代碼將以下所示:
<form method="POST">
<span name="*.errors">Field is required.<br/>Field is required.</span>
<table>
<tr>
<td>First Name:</td>
<td><input name="firstName" type="text" value=""/></td>
<td><span name="firstName.errors">Field is required.</span></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input name="lastName" type="text" value=""/></td>
<td><span name="lastName.errors">Field is required.</span></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="Save Changes" />
</td>
</tr>
</form>