??在《Spring MVC的常用注解(學(xué)習(xí)筆記)》中提到了使用@ModelAttribute注解,利用Model和ModelMap來(lái)存儲(chǔ)數(shù)據(jù)模型。例如下面的代碼表示將user對(duì)象添加到model的“user”屬性中。
@ModelAttribute
public void userModel(String loginname,String password,Model model){
//創(chuàng)建User對(duì)象存儲(chǔ)jsp頁(yè)面?zhèn)魅氲膮?shù)
...
//將USer對(duì)象添加到Model當(dāng)中
model.addAttribute("user",user);
}
然后就可以在JSP頁(yè)面通過(guò)requestScope訪問(wèn)得到。
form標(biāo)簽
??而這里要介紹的form標(biāo)簽同樣需要利用到Model,它可以自動(dòng)綁定Model中的一個(gè)屬性值到當(dāng)前form對(duì)應(yīng)的實(shí)體對(duì)象,默認(rèn)為command屬性。form標(biāo)簽雖然是JSP頁(yè)面的標(biāo)簽,但是這里強(qiáng)大的是和Controller中的變量交互的功能。
@Controller
public class UserController{
@RequestMapping(value="/registerForm",method=RequestMethod.GET)
public String registerForm(Model model) {
User user = new User("jack","男",28);
// model中添加屬性command,值是user對(duì)象
model.addAttribute("command",user);
return "registerForm";
}
}
??在JSP頁(yè)面中就能夠通過(guò)form標(biāo)簽獲取到具體的值。
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<form:form method="post" action="...">
...
<form:input path="username">
...
</form:form>
??假設(shè)User類中定義的屬性為username,那么通過(guò)<form:input path="username">就能夠獲取到對(duì)應(yīng)的值,也就是“jacky”。如果不想使用默認(rèn)的Model的command屬性,而是想使用其他的屬性時(shí),可以使用form標(biāo)簽的modelAttribute屬性或者commandName屬性進(jìn)行指定,這里以modelAttribute屬性為例。
<form:form modelAttribute="user" mothod="post" action="...">
??這么多的標(biāo)簽,實(shí)現(xiàn)的步驟都有些一致。input中文本框的默認(rèn)顯示值、checkbox、radiobutton、下拉菜單的默認(rèn)選擇值現(xiàn)在都可以不在Html中直接指定,而是通過(guò)Model的屬性來(lái)指定。一般而言,在Model中設(shè)置兩個(gè)屬性,一個(gè)用于存放需要勾選的選項(xiàng),另外一個(gè)用于存放需要顯示出來(lái)的所有可選值。而input標(biāo)簽不需要顯示多余的選項(xiàng)。
??在input標(biāo)簽中,使用modelAttribute屬性指向Model的“user”屬性,從而獲取到一個(gè)user對(duì)象,在input頁(yè)面直接可以訪問(wèn):這樣就會(huì)顯示默認(rèn)的username的值。
<form:input path="username">
checkbox標(biāo)簽等的實(shí)現(xiàn)
??而其它需要展示多余選項(xiàng)的如何操作呢。下面只舉checkbox為例。
思路一:
??以checkbox標(biāo)簽為例,第一種思路是直接在jsp頁(yè)面中將所有的可選項(xiàng)列出來(lái)。
<form:form modelAttribute="user" mothod="post" action="...">
...
<form:checkbox path="courses" value="JAVAEE" label="JAVAEE"/>
<form:checkbox path="courses" value="Mybatis" label="Mybatis"/>
<form:checkbox path="courses" value="Spring" label="Spring"/>
??首先創(chuàng)建一個(gè)User類用于存放要展示出來(lái)的數(shù)據(jù)。User類有reader和courses兩個(gè)屬性。reader是boolean類型變量,設(shè)置為true的話,在頁(yè)面中的checkbox復(fù)選框就會(huì)被選中。而courses是一個(gè)List<String>類型變量。所以在Controller中創(chuàng)建一個(gè)user對(duì)象,然后將reader屬性設(shè)置為true,并且將“JavaEE”添加到一個(gè)list中,然后將該list傳遞給courses屬性,這樣的話JSP頁(yè)面中JAVAEE對(duì)應(yīng)的選項(xiàng)就會(huì)被選中。
思路二:
??第二種思路是不在JSP頁(yè)面中將可選項(xiàng)列出來(lái),無(wú)論是可選項(xiàng)還是被選中項(xiàng)全部都在Controller中進(jìn)行實(shí)現(xiàn)。這樣的話,JSP頁(yè)面中上面的代碼就變成:
<form:checkbox items="${courseList}" path="coureses" >
??也就是說(shuō)原來(lái)<form:checkbox>標(biāo)簽中的value屬性和label屬性都消失了。但是多了一個(gè)items屬性。這時(shí)候的User類只有一個(gè)courses屬性,是一個(gè)List<String>類型的變量。也就是說(shuō)User類可以保存一個(gè)List對(duì)象到其courses屬性之中(這跟思路一的操作差別不大)。
??在Controller中新建一個(gè)user對(duì)象,然后新建一個(gè)List(并將“JAVAEE”添加到該list中),到這為止跟第一種思路都是基本一樣的操作。但是在這里,還需要另外創(chuàng)建一個(gè)List,用于保存所有的可選項(xiàng)。
List<String> courseList = new ArrayList<String>();
courseList.add("JAVAEE");
courseList.add("Mybatis");
courseList.add("Spring");
model.addAttribute("user",user);
model.addAttribute("courseList",courseList);
這里model需要設(shè)置兩個(gè)屬性。一個(gè)用于設(shè)置勾選項(xiàng),一個(gè)用于設(shè)置所有可選項(xiàng)。
<form:checkbox items="${courseList}" path="coureses" >
??然后就可以通過(guò)這樣在JSP頁(yè)面進(jìn)行顯示了。如果希望呈現(xiàn)出來(lái)的Lable和Value值不同,那么就可以創(chuàng)建一個(gè)Map來(lái)替代上面的List,這時(shí)候Map的value作為L(zhǎng)abel進(jìn)行顯示,而key則是真正的復(fù)選框的value。例如:
Map<String,String> courseMap = new HashMap<String ,String>();
courseMap.put("1","JAVAEE");
courseMap.put("2","Mybatis")
courseMap.put("3","Spring");
??并且這時(shí)候user對(duì)象添加的List中,添加的不是Map的值,而是key的值(例如原來(lái)要添加“JAVAEE”到list中,然后把list保存到user對(duì)象中,現(xiàn)在則是添加“1”到list中,然后把list保存到user對(duì)象中)。
??這還沒(méi)完,還有一種情況是需要添加對(duì)象的。也是使用的思路二中List的原理,不需要使用Map,但是由于需要?jiǎng)?chuàng)建對(duì)象,所以顯得繁瑣一些。同樣,這時(shí)候Model設(shè)置兩個(gè)屬性,一個(gè)用于指向?qū)ο?存儲(chǔ)了勾選項(xiàng)),一個(gè)用于指向列表(存儲(chǔ)了所有可選項(xiàng)),這跟之前的還是一樣,不同的地方在于指向的列表是一個(gè)對(duì)象列表。
??一個(gè)Employee可能具有多個(gè)不同的部門。所以Employee有一個(gè)depts屬性,它是一個(gè)List<Dept>類型的變量,用于記錄屬于哪些部門。
model.addAttribute("employee",employee);
model.addAttribute("deptList",deptList);
??其實(shí),我們所選擇的可選項(xiàng)都是同屬于某一個(gè)對(duì)象的屬性,可能是一個(gè)屬性中的多個(gè)列表元素,也可能是多個(gè)屬性。例如(username,sex,age),再比如(JAVAEE,Mybatis,Spring),前者是user這個(gè)對(duì)象的多個(gè)屬性,后者都是User的某一屬性(courses)的列表元素。而這里要顯示出來(lái)的各個(gè)部門都存在于Employee這個(gè)類的depts屬性中。depts是一個(gè)List<dept>類型的屬性。所以也是某一屬性的列表元素。
??也正是因?yàn)檫@里depts是一個(gè)List<dept>而非List<String>類型的變量,所以在該例子中的操作會(huì)顯得稍微繁瑣一些。需要?jiǎng)?chuàng)建對(duì)象,并且將對(duì)象保存到List中傳遞給Employee的depts屬性。而如果是List<String>類型,那么就可以略去創(chuàng)建對(duì)象的步驟,直接將字符串添加到列表繼而傳遞給depts屬性。