(七)利用ajax發(fā)送Post請(qǐng)求到后臺(tái)
上一節(jié)陶珠,我們大致講了利用ajax發(fā)送Get請(qǐng)求到后臺(tái)服務(wù)畜隶,這一節(jié)犯犁,我們來(lái)講解發(fā)送post請(qǐng)求
一般說(shuō)來(lái)属愤,我們獲取信息使用Get請(qǐng)求,向后臺(tái)請(qǐng)求某些信息酸役;使用Post請(qǐng)求向后臺(tái)發(fā)送一些信息住诸,而其他幾種方法,比如Put涣澡,Delete等贱呐,受制于瀏覽器,tomcat版本等等入桂,不一定都能使用奄薇。
但是這些都非絕對(duì),使用get發(fā)送信息抗愁,使用post獲取信息馁蒂,也是有的,都是請(qǐng)求蜘腌,并不拘泥于理論沫屡,看實(shí)際使用場(chǎng)景的。
首先逢捺,我們還是準(zhǔn)備一個(gè)工程谁鳍,就用之前的工程。
頁(yè)面中劫瞳,發(fā)送一個(gè)ajax post請(qǐng)求倘潜,主要代碼如下
$("#POSTButton").click(function(){
let id = $("#myInput").val();
$.ajax({
url:basePath+"/firstPost",
data:id,
type:'POST',
dataType:'text',
contentType:'application/json',
success:function(result){
$("#myInput").val(result);
}
})
});
這個(gè)跟之前get方法一樣的結(jié)構(gòu),只是type那里方法是POST
然后后臺(tái)服務(wù)那里志于,我們接受這個(gè)請(qǐng)求的方法涮因,只需要將method寫(xiě)成post即可
@ResponseBody
@RequestMapping(value="/firstPost",method=RequestMethod.POST)
public String myFirstPost(@RequestBody String msg){
System.out.println("from page msg:"+msg);
return "Good "+msg;
}
關(guān)鍵語(yǔ)句就是 method=RequestMethod.POST
限定這個(gè)方法只接受post請(qǐng)求,如果發(fā)送get請(qǐng)求伺绽,服務(wù)器會(huì)報(bào)405錯(cuò)錯(cuò)誤
好了养泡,這個(gè)是post的基本設(shè)定,接下來(lái)奈应,關(guān)鍵就在于data的形式澜掩,不同形態(tài)的data,后端接受這個(gè)data的方式就不一樣
1. 最簡(jiǎn)單的方式
我們可以學(xué)get
方法那樣杖挣,把post參數(shù)寫(xiě)在url后面肩榕,就是傳統(tǒng)的方式,例如
http://test.com?user=Joe&age=12
通過(guò)這種方式惩妇,將用戶Joe上傳給服務(wù)器
那么株汉,我們的js代碼就這樣寫(xiě)
$("#POSTButton").click(function(){
let user = 'Joe';
let age = 12;
$.ajax({
url:basePath+"/firstPost"+"?user="+user+"&age="+age,
type:'POST',
dataType:'text',
contentType:'text/plain',
success:function(result){
$("#myInput").val(result);
}
})
});
java后臺(tái)接受這個(gè)參數(shù)的controller方法這樣寫(xiě)
@ResponseBody
@RequestMapping(value="/firstPost",method=RequestMethod.POST)
public String myFirstPost(String user,Integer age){
System.out.println("from page user:"+user);
System.out.println("from page age:"+age);
return "Good";
}
把工程運(yùn)行起來(lái),在瀏覽器訪問(wèn)
http://localhost:12344/springstart/hello
這里端口寫(xiě)你自己設(shè)置的端口
點(diǎn)擊頁(yè)面上的 post按鈕歌殃,可以在后臺(tái)代碼中看到打印輸出
from page user:Joe
from page age:12
這個(gè)是最簡(jiǎn)單的一種方式乔妈,當(dāng)然,這只比較非主流的方式
一般post的參數(shù)不會(huì)寫(xiě)在鏈接中
其次氓皱,如果有安全性要求的話路召,使用https請(qǐng)求,寫(xiě)在鏈接中是無(wú)法加密的
所以一般不會(huì)使用這種方式波材。
2. 最常見(jiàn)的方式
目前最常見(jiàn)的方式就是使用json格式傳送數(shù)據(jù)
使用json格式表達(dá)我們的上面的user的話股淡,大概是這樣:
{
"name":"Joe",
"age":12
}
json格式是現(xiàn)在最流行的一種數(shù)據(jù)格式,被使用在各個(gè)場(chǎng)景下各聘,幾乎所有語(yǔ)言都支持json格式的解析揣非。具體的相關(guān)格式,請(qǐng)自行百度躲因。
我們的js代碼這樣寫(xiě):
$("#POSTButton").click(function(){
let oneUser = new Object();
oneUser.name = 'Joe';
oneUser.age = 12;
let msg = JSON.stringify(oneUser);
$.ajax({
url:basePath+"/firstPost2",
type:'POST',
data:msg,
dataType:'json',
contentType:'application/json',
success:function(result){
$("#myInput").val(result);
}
})
});
這里早敬,我們把usl改了一點(diǎn)
url:basePath+"/firstPost2"
與之前的接口不同,這里使用 firstPost2
大脉,以便后臺(tái)能保留前面的方法搞监。
我們創(chuàng)建了一個(gè)對(duì)象,把用戶的參數(shù)給它镰矿,然后琐驴,使用 JSON.stringify
將這個(gè)對(duì)象轉(zhuǎn)為json字符串
然后,在ajax的參數(shù)中,有些變動(dòng)
dataType:'json'
contentType:'application/json'
這兩個(gè)表明绝淡,我們發(fā)送出去的數(shù)據(jù)宙刘,是json
對(duì)應(yīng)的,我們的后臺(tái)接收數(shù)據(jù)的方法牢酵,需要適當(dāng)修改一下
@ResponseBody
@RequestMapping(value="/firstPost2",method=RequestMethod.POST)
public String myFirstPost2(@RequestBody User user){
System.out.println("from page user:"+user.toString());
return "Good";
}
與之前方法的差別就是參數(shù)
@RequestBody User user
首先悬包,注解 @RequestBody
用來(lái)將頁(yè)面?zhèn)魉瓦^(guò)來(lái)的json結(jié)果,對(duì)應(yīng)到我們的接收實(shí)例上面馍乙,這里布近,我們的實(shí)例是user
package com.springstart.model;
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
這種只有屬性以及屬性對(duì)應(yīng)的set,get的類丝格,有的地方叫POJO類
撑瞧,有的地方叫java bean
,不管叫什么显蝌,深究起來(lái)也沒(méi)意義预伺,這種類型的類,在web后臺(tái)開(kāi)發(fā)中很常見(jiàn)琅束,有時(shí)候會(huì)在一個(gè)web后臺(tái)項(xiàng)目源碼中占很大比例扭屁。
這種類,其作用涩禀,就是保存數(shù)據(jù)使用料滥,有時(shí)候保存頁(yè)面過(guò)來(lái)的數(shù)據(jù),有時(shí)候保存從數(shù)據(jù)庫(kù)查詢的數(shù)據(jù)艾船,一般來(lái)說(shuō)葵腹,set
和get
方法必須有,不排除一些比較智能的框架自動(dòng)匹配的情況屿岂,然后就是一些其他的方法践宴,比如用于跟蹤數(shù)據(jù)的toString
,將指定的成員變量組裝起來(lái)成為一個(gè)字符串爷怀,便于日志記錄或者打印輸出阻肩。
現(xiàn)在的IDE都具備自動(dòng)生成set
和get
等方法的機(jī)制,只需要將成員變量定義出來(lái)即可运授,不會(huì)用的自行百度自己使用的IDE如何自動(dòng)生成烤惊。
這里,我們使用User類來(lái)接收頁(yè)面給過(guò)來(lái)的json數(shù)據(jù)吁朦,User類成員變量和頁(yè)面的json數(shù)據(jù)一一對(duì)應(yīng)柒室,這樣拿下來(lái)就可以直接使用。正如我們代碼中的逗宜,使用toString將參數(shù)輸出雄右。
當(dāng)然空骚,我們也可以不用類去接收,使用字符串也可以擂仍。
@ResponseBody
@RequestMapping(value="/firstPost2",method=RequestMethod.POST)
public String myFirstPost2(@RequestBody String msg){
System.out.println("from page user:"+msg);
return "Good";
}
這樣囤屹,會(huì)把a(bǔ)jax提交上來(lái)的json字符串,放到msg中防楷。
上面這種方式牺丙,是一種萬(wàn)精油的方式则涯,任何前端和后臺(tái)复局,都可以這么寫(xiě),只要前端給到后臺(tái)的數(shù)據(jù)粟判,組合成json即可亿昏,后臺(tái)拿到數(shù)據(jù)后自己處理,如何使用档礁,持久化等角钩,都沒(méi)有問(wèn)題。
3.提交form
form
在頁(yè)面上呻澜,一般叫做表單递礼,在form
下,有多個(gè)數(shù)據(jù)羹幸,用戶可以填寫(xiě)后一次性提交脊髓,平時(shí)我們填寫(xiě)的登陸,注冊(cè)等栅受,都是在一個(gè)表單上執(zhí)行的将硝。
這里,我們寫(xiě)一個(gè)簡(jiǎn)單的表達(dá)屏镊,用戶輸入用戶名和密碼依疼,模擬用戶登陸。
<span>表單demo</span>
<form id="formDemo">
<label>用戶名:</label>
<input id="name" name="name"/>
<br>
<label>密碼:</label>
<input id="passwd" name="passwd" type="password"/>
<br>
<button id="formButton" type="button">提交</button>
</form>
在jsp中我們加一段這個(gè)而芥,這里就是一個(gè)簡(jiǎn)單的form
律罢,里面有兩個(gè)input
,每個(gè)input
都需要有name
屬性棍丐,因?yàn)?code>form在提取里面的字段的時(shí)候误辑,是以name
作為變量名的。
然后骄酗,這里有個(gè)button
稀余,類型type="button"
,如果不寫(xiě)這個(gè)type
趋翻,那么button
在被點(diǎn)擊時(shí)睛琳,會(huì)自動(dòng)提交盒蟆,button
的默認(rèn)類型是submit
,我們這里希望從js里面通過(guò)ajax提交师骗。
這個(gè)form
在頁(yè)面顯示出來(lái)
不用在乎樣式历等,能用就行。
對(duì)應(yīng)的辟癌,我們?cè)趈s里面寒屯,寫(xiě)一段button點(diǎn)擊觸發(fā)的函數(shù)。
這里黍少,對(duì)于form
數(shù)據(jù)的處理方式有很多種寡夹,我們這里講一下最普通的做法。
$("#formButton").click(function () {
let msg = $("#formDemo").serialize();
$.ajax({
url:basePath+"/firstPostForm",
type:'POST',
data:formData,
success:function(result){
$("#myInput").val(result);
}
})
});
這里的關(guān)鍵代碼是
let msg = $("#formDemo").serialize();
將form
的數(shù)據(jù)序列化厂置,通過(guò)調(diào)試打斷點(diǎn)菩掏,我們可以看到msg的結(jié)構(gòu)類似于
name=Joe&passwd=123
實(shí)際就是把form
中的參數(shù)一個(gè)一個(gè)的用&
連接起來(lái)
我們的接收方式有幾種
@ResponseBody
@RequestMapping(value="/firstPostFrom",method=RequestMethod.POST)
public String myFirstPost3(HttpServletRequest request){
System.out.println("from page login:"+request.getParameter("name"));
return "Good";
}
HttpServletRequest request
是獲取參數(shù)的通用方式
@ResponseBody
@RequestMapping(value="/firstPostFrom",method=RequestMethod.POST)
public String myFirstPost3(String name,String passwd){
System.out.println("from page login,name:"+name);
return "Good";
}
直接把給過(guò)來(lái)的參數(shù)寫(xiě)到方法的參數(shù)中,一一對(duì)應(yīng)即可
我們也可以寫(xiě)一個(gè)類來(lái)接收
package com.springstart.model;
public class Login {
private String name;
private String passwd;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
@Override
public String toString() {
return "Login{" +
"name='" + name + '\'' +
", passwd='" + passwd + '\'' +
'}';
}
}
@ResponseBody
@RequestMapping(value="/firstPostForm",method=RequestMethod.POST)
public String myFirstPost3(Login login){
System.out.println("from page login,name:"+login.getName());
return "Good";
}
這里數(shù)據(jù)不是用json發(fā)送過(guò)來(lái)的昵济,所以不用加注解智绸,直接就能轉(zhuǎn)換過(guò)來(lái)。
從上面的方法我們可以看出访忿,完全可以把form中的參數(shù)一個(gè)一個(gè)的讀取出來(lái)瞧栗,組合成json來(lái)傳輸,現(xiàn)在一些前端頁(yè)面已經(jīng)不再使用form的形式了海铆。
但是迹恐,如果要上傳文件,使用form會(huì)簡(jiǎn)單一些游添,我們下一篇再講系草。
本文源碼
springstart github post_demo,請(qǐng)自行下載