SpringMVC學習系列(5) 之 數據綁定-2


在系列(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>

運行測試:

1

可以看到已經獲取到了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>

運行測試:

2

可以看到已經獲取到了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";
}

運行測試:

3

可以看到依然成功的綁定了提交的數據。

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>

運行測試:

4

5

6

可以看到我們已經成功的分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

結果正確,證明轉換成功。

7.@RequestPart 綁定“multipart/form-data“類型數據,支持javax.servlet.http.Part文件上傳,並可可以進行類型轉換,詳見官方文檔:

http://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/htmlsingle/#new-in-3.1-mvc-requestpart

 

代碼下載:http://pan.baidu.com/s/1hqqVLTa 

 

數據綁定部分的內容到此結束。

 

注: 之前沒注意前11篇的示例代碼,不知道為什么當時打包上傳上去的是沒有.project項目文件的,導致下載后不能直接導入eclipse運行,虛擬機又 被我刪掉了,這些示例代碼也沒有備份,但是代碼文件還在的,所以可以新建一個Dynamic Web Project把對應的配置文件和controller還有view導入就可以了,給大家造成的不便說聲抱歉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM