在系列(4)中我們介紹了如何用@RequestParam來綁定數據,下面我們來看一下其它幾個數據綁定注解的使用方法。
1.@PathVariable 用來綁定URL模板變量值,這個我們已經在系列(3)中介紹了使用方法,這里不在贅述。
2.@CookieValue 用來綁定Cookie中的數據。下面我們用獲取Cookie中的sessionId做測試:
在DataBindController添加cookiebind action,代碼如下:
//@CookieValue Test @RequestMapping(value="/cookiebind", method = {RequestMethod.GET}) public String cookieBind(HttpServletRequest request, Model model, @CookieValue(value="JSESSIONID", defaultValue="") String jsessionId){ model.addAttribute("jsessionId", jsessionId); return "cookiebindresult"; }
在views文件夾中添加一個cookiebindresult.jsp視圖,代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> ${jsessionId} </body> </html>
運行測試:
可以看到已經獲取到了sessionId。
注:@CookieValue 與@RequestParam 一樣也有3個參數,其含義與的@RequestParam 參數含義相同。
3.@RequestHeader 用來綁定請求頭中的數據,我們用@RequestHeader獲取User-Agent 來做演示:
在DataBindController添加requestheaderbind action,代碼如下:
//@RequestHeader Test @RequestMapping(value="/requestheaderbind", method = {RequestMethod.GET}) public String requestHeaderBind(HttpServletRequest request, Model model, @RequestHeader(value="User-Agent", defaultValue="") String userAgent){ model.addAttribute("userAgent", userAgent); return "requestheaderbindresult"; }
在views文件夾中添加一個requestheaderbindresult.jsp視圖,代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> ${userAgent} </body> </html>
運行測試:
可以看到已經獲取到了User-Agent 。
注:@RequestHeader 與@RequestParam 一樣也有3個參數,其含義與的@RequestParam 參數含義相同。
4.@ModelAttribute 綁定數據到模型中。在系列(4)的modelAutoBind action中我們將表單提交的數據添加到Model中的代碼如下:
@RequestMapping(value="/modelautobind", method = {RequestMethod.POST}) public String modelAutoBind(HttpServletRequest request, Model model, AccountModel accountModel){ model.addAttribute("accountmodel", accountModel); return "modelautobindresult"; }
而借助於@ModelAttribute 我們可以更簡單的講數據添加到Model中,把上面的代碼修改為:
@RequestMapping(value="/modelautobind", method = {RequestMethod.POST}) public String modelAutoBind(HttpServletRequest request, @ModelAttribute("accountmodel") AccountModel accountModel){ return "modelautobindresult"; }
運行測試:
可以看到依然成功的綁定了提交的數據。
5.Model中的數據作用域是Request級別的,也就是說在一個Request請求中是獲取不到其它Request請求的Model的數據的。但我們可以用@SessionAttributes 把數據存儲到session中,來保持多次請求間數據,這樣就可以來實現比如分步驟提交表單等需求。下面我們來看如何分2步把數據綁定到AccountModel中:
在DataBindController上添加:
@SessionAttributes(value = "sessionaccountmodel")
在DataBindController添加usernamebind和passwordbind action,代碼如下:
//@SessionAttributes Test @ModelAttribute("sessionaccountmodel") public AccountModel initAccountModel(){ return new AccountModel(); } @RequestMapping(value="/usernamebind", method = {RequestMethod.GET}) public String userNameBind( Model model, AccountModel accountModel){ model.addAttribute("sessionaccountmodel", new AccountModel()); return "usernamebind"; } @RequestMapping(value="/usernamebind", method = {RequestMethod.POST}) public String userNameBindPost( @ModelAttribute("sessionaccountmodel") AccountModel accountModel){ //重定向到密碼綁定測試 return "redirect:passwordbind"; } @RequestMapping(value="/passwordbind", method = {RequestMethod.GET}) public String passwordBind(@ModelAttribute("sessionaccountmodel") AccountModel accountModel){ return "passwordbind"; } @RequestMapping(value="/passwordbind", method = {RequestMethod.POST}) public String passwordBindPost(@ModelAttribute("sessionaccountmodel") AccountModel accountModel, SessionStatus status){ //銷毀@SessionAttributes存儲的對象 status.setComplete(); //顯示綁定結果 return "sessionmodelbindresult"; }
由於我們在controller上指定了@SessionAttributes,所以在@ModelAttribute(“xxx”)注解的參數會直接在@SessionAttributes中查找名為”xxx”的對象,如果沒有找到則調用@ModelAttribute(“xxx”)注解的方法返回對象並存入@SessionAttributes(如果沒有找到且沒有@ModelAttribute(“xxx”)注解的方法就會拋出HttpSessionRequiredException)。當執行到最后一步就可以調用SessionStatus .setComplete()方法把@SessionAttributes中保存對象銷毀了(不會清除HttpSession中的數據)。
在views文件夾中添加usernamebind.jsp、passwordbind.jsp和sessionmodelbindresult.jsp視圖內容分別如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form:form modelAttribute="sessionaccountmodel" method="post"> 用戶名:<form:input path="username"/><br/> <input type="submit" value="Submit" /> </form:form> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form:form modelAttribute="sessionaccountmodel" method="post"> 密 碼:<form:password path="password"/><br/> <input type="submit" value="Submit" /> </form:form> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 用戶名:${sessionaccountmodel.username}<br/> 密 碼:${sessionaccountmodel.password} </body> </html>
運行測試:
可以看到我們已經成功的分2步把數據綁定到AccountModel中了。
注:
@SessionAttributes有value和types兩個參數其中value指明要對象的名稱,types指定要綁定對象的類型,如@SessionAttributes(value = "sessionaccountmodel", types=AccountModel.class)兩者是and關系,需要同時滿足。也可以同時指定多個value和types 如:@SessionAttributes(value = {"aa", "aa"} , types={XXX.class, YYY.class}) 。
6.@RequestBody 調用合適的MessageConvert來把非application/x-www-form-urlencoded請求中的內容轉換為指定的對象它通常與@ResponseBody合用,@ResponseBody與.@RequestBody剛好相反,他把指定的對象轉換為合適的內容(請求頭為Accept:application/json 則返回json數據)並返回。這里我們用一個ajax請求做演示:
由於Spring默認解析json用的是Jackson,所以我們這里要把jackson-core-asl-1.9.13.jar和jackson-mapper-asl-1.9.13.jar兩個包添加到我們項目。
修改AccountModel讓其繼承Serializable接口,並添加一個空的構造函數(為了Jackson做轉換)。
在DataBindController添加requestBodyBindaction,代碼如下:
//@RequestBody Test @RequestMapping(value="/requestbodybind", method = {RequestMethod.GET}) public String requestBodyBind(Model model){ model.addAttribute("accountmodel", new AccountModel()); return "requestbodybind"; } @RequestMapping(value="/requestbodybind", method = {RequestMethod.POST}) public @ResponseBody AccountModel requestBodyBind(@RequestBody AccountModel accountModel){ return accountModel; }
在views文件夾中添加requestbodybind.jsp視圖內容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <html> <head> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form:form modelAttribute="accountmodel" method="post"> 用戶名:<form:input path="username"/><br/> 密 碼:<form:password path="password"/><br/> <input type="button" id="submit" value="Submit" /> </form:form> <script type="text/javascript"> $(function() { $("#submit").click(function() { var postdata = '{"username":"' + $('#username').val() + '","password":"' + $('#password').val() + '"}'; $.ajax({ type : 'POST', contentType : 'application/json', url : 'http://localhost:8080/SpringMVCLesson/databind/requestbodybind', processData : false, dataType : 'json', data : postdata, success : function(data) { alert('username : '+data.username+'\npassword : '+data.password); }, error : function() { alert('error...'); } }); }); }); </script> </body> </html>
運行測試:
結果正確,證明轉換成功。
7.@RequestPart 綁定“multipart/form-data“類型數據,支持javax.servlet.http.Part文件上傳,並可可以進行類型轉換,詳見官方文檔:
代碼下載:http://pan.baidu.com/s/1hqqVLTa
數據綁定部分的內容到此結束。
注: 之前沒注意前11篇的示例代碼,不知道為什么當時打包上傳上去的是沒有.project項目文件的,導致下載后不能直接導入eclipse運行,虛擬機又 被我刪掉了,這些示例代碼也沒有備份,但是代碼文件還在的,所以可以新建一個Dynamic Web Project把對應的配置文件和controller還有view導入就可以了,給大家造成的不便說聲抱歉。