SpringMVC和AJAX交互


在實際開發中我們經常需要前后台交互,那么springmvc與ajax之間交互這里記錄下在實際開發中遇到的細節問題。

jsp頁面:

1 <fieldset id="login" style="width:600px; border:1px solid #000;border-left:none;border-right:none"> 
2 <legend style="">用戶登錄</legend> 
3 <p align="center">賬號:<input type="text" name="username" /></p> 
4 <p align="center">密碼:<input type="password" name="password" /></p> 
5 <p align="center"><input type="submit" id="submit1" value="登錄" /></p> 
6 </fieldset>

ajax請求如下:

<script type="text/javascript">
$(function() {
$("#submit1").click(function() {
var json = {
'username':$(':input[name=username]').val(),
'password':$(':input[name=password]').val()
};
//json字符串 {"username":"admin","password":"123456"}
var postdata = JSON.stringify(json);//json對象轉換json字符串
alert(postdata);
$.ajax({
type : 'POST',
contentType : 'application/json',//注意類型
/**
*(默認: true) 默認情況下,通過data選項傳遞進來的數據,如果是一個對象(技術上講只要不是字符串),
* 都會處理轉化成一個查詢字符串,以配合默認內容類型 "application/x-www-form-urlencoded"。
* 如果要發送 DOM 樹信息或其它不希望轉換的信息,請設置為 false。
*/
processData : false,
url : '<%=path%>/databind/requestbodybind',
dataType : 'json',
data : postdata,
success : function(data) {
alert('username : '+data.username+'\npassword : '+data.password);
},
error : function() {
alert('error...');
}
});
});    
});
</script> 

tip:我們可以看到在用contentType : ‘application/json’發起請求,data我們傳的是一個json字符串,而不是json對象,一開始我也認為是可以的,結果不行,直接傳對象報錯,不妨親自試試。
SpringMVC需要提供的方法如下:

@RequestMapping(value="requestbodybind", method = {RequestMethod.POST})
@ResponseBody
public Account requestBodyBind(@RequestBody Account account){
System.out.println("requestbodybind:" + account);
return account;
}

那還是contentType : ‘application/json’發起的請求,我們能不能用如下的方式接收值呢

@RequestMapping(value="json", method = {RequestMethod.POST})
@ResponseBody
public Account json(String username, String password){
Account account = new Account();
account.setUsername(username);
account.setPassword(password);
return account;
}

答案是不可以的,會拋異常,400 Bad Request
究其原因是:contentType : ‘application/json’數據發送后台接收必須是Modle,不能是單個屬性,且必須加上@RequestBody注解。
如果我們把contentType換成默認的contentType : ‘application/x-www-form-urlencoded’呢,前后台又該怎么寫?

ajax寫法如下:

$(function(){
$("#submit").click(function(){
$.ajax({
type: "POST",
/* contentType : 'application/x-www-form-urlencoded',*/
url: '<%=path%>/databind/json',
dataType: "json",
data: {username:$('#username').val(),
password:$('#password').val()},
success: function(data){
alert('username : '+data.username+'\npassword : '+data.password);
}
}); 
});
});

這里不得不提下,雖然data這里看起來傳的是一個json對象,但由於使用了application/x-www-form-urlencoded,最終可以通過firebug可以看到,其實最終傳過去的還是username=admin&password=123456,當然你也可以直接傳字符串過去,但是有一點要注意,真實項目中字段還是特別多的,這樣拼接會相當繁瑣,然而我們知道還有個方法供我們使用,jQuery給我們提供的$(“#login”).serialize()序列化表單。

$(function(){
$("#submit").click(function(){
var params = $("#login").serialize();//序列化表單
alert(params);
$.ajax({
type: "POST",
url: '<%=path%>/databind/json',
dataType: "json",
data: params,
success: function(data){
alert('username : '+data.username+'\npassword : '+data.password);
}
}); 
});
});

后台接收方式如下:

@RequestMapping(value="json", method = {RequestMethod.POST})
@ResponseBody
public Account json(String username,String password){
Account account = new Account();
account.setUsername(username);
account.setPassword(password);
return account;
}

那這里要提出一個疑問,如果我需要接受的字段特別多呢,難道我在方法中也需要一個一個參數的去寫嘛,比如有20個,還不得累死。
答案是當然啦

@RequestMapping(value="/json", method = {RequestMethod.POST})
@ResponseBody
public Account json(Account account){
System.out.println(account);
return account;
}

此外,這里不得不提一件事情,很多人一看到要拿model接收傳參,就想着應該是不是應該加上@RequestBody注解,springmvc才會幫你把相關值封裝到model里面去,我在這里告訴你,千萬不要這樣想,這個注解不是隨便就用的,它的用途是幫你轉換json->model、 xml->model,你好好的表單提交,用的contentType:application/x-www-form-urlencoded,何必畫蛇添足加上這個注解呢。
總結:

<script type="text/javascript">
$(function() {
$("#submit1").click(function() {
var json = {
'username':$(':input[name=username]').val(),
'password':$(':input[name=password]').val()
};
//json字符串 {"username":"admin","password":"123456"}
var postdata = JSON.stringify(json);//json對象轉換json字符串
alert(postdata);
$.ajax({
type : 'POST',
contentType : 'application/json',
/**
*(默認: true) 默認情況下,通過data選項傳遞進來的數據,如果是一個對象(技術上講只要不是字符串),
* 都會處理轉化成一個查詢字符串,以配合默認內容類型 "application/x-www-form-urlencoded"。
* 如果要發送 DOM 樹信息或其它不希望轉換的信息,請設置為 false。
*/
processData : false,
url : '<%=path%>/databind/requestbodybind',
dataType : 'json',
data : postdata,
success : function(data) {
alert('username : '+data.username+'\npassword : '+data.password);
},
error : function() {
alert('error...');
}
});
});    
});
</script> 

以上$.ajax()中 contentType : 'application/json',則data必須轉換為json對象且后台方法參數必須用model接受,否則報400錯誤,則后台接受參數為:

@RequestMapping(value="requestbodybind", method = {RequestMethod.POST})
@ResponseBody
public Account requestBodyBind(@RequestBody Account account){
System.out.println("requestbodybind:" + account);
return account;
}

默認$.ajax()中的contentType:'application/x-www-form-urlencoded'發送的數據格式為“xx=yy&uu=ii”data數據不是json對象,它是發送信息至服務器時內容編碼類型。
如下$.ajax()沒有寫contentType則默認類型為'application/x-www-form-urlencoded',則data傳遞的參數類型為單個屬性.

function initArrivePerson(divId) {
var jqids = $("#jqid").val();//獲得警情id
$.ajax({
type:"post", 
url:basePath + "kscj/findArrivePerson.do",
data:{"jqid":jqids},
dataType:"json",
async: false,
cache:false,
success : function(data) {
$("#"+divId).html("");
var arrivePerson="";
for (var i=0;i<data.length;i++) {
arrivePerson+="<span>";
arrivePerson+="<input type=\"checkbox\" name=\"cjrxm\" value=\'"+data[i].sjybh+"\'/><span>"+data[i].sjyxm+"</span>";
arrivePerson+="<input type=\"hidden\" name=\"cjdbh\" value=\'"+data[i].cjdbh+"\'/>";
arrivePerson+="</span>";
}
$("#"+divId).append(arrivePerson); 
}
});
}

則后台接受參數為:

@RequestMapping(value = "/findArrivePerson", produces = {"application/json;charset=UTF-8"})
@ResponseBody
public List<TItmpTcsDisposal> findArrivePerson(HttpServletRequest req, HttpServletResponse resp, String jqid){
List<TItmpTcsDisposal> arriveList = titmpGpsLocateinfoService.findNoRepeat(jqid);
return arriveList;
}

補充:

什么時候該用@RequestParam注解,什么時候不該用

前面我們已經看到了,接受單個基本類型值的參數,只要在方法中分別寫下,並且並不需要使用什么注解就能拿到傳過來的值,那為什么還有@RequestParam這個注解呢,並且看到很多地方都在用。
其實呢這個注解,有它的用處,並不是一無是處,首先作為基本類型的參數,如果不使用注解,是可傳可不傳的,如果為null並不會報錯,但當你使用了@RequestParam注解,那么此時該參數就是必傳的了,如果不傳就會報錯,然而還是可以通過配置來讓其可不必傳,如@RequestParam(value=”username”, required=false),此外,該注解還可以設置如果前台沒有傳值過來,會給一個默認值,如@RequestParam(value=”username”, defaultValue=”ruo”)。
我對該注解做的總結是:如果你某個參數不是必傳的,就別用它了,如果是必傳的,請一定用上它,如果必傳參數可以有默認值的話,還請加上defaultValue默認值。

博客原文:https://blog.csdn.net/u014079773/article/details/52984747


免責聲明!

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



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