眾所周知jsp是已經(jīng)入土的技術(shù),雖然仍有不少老項(xiàng)目在用,但已經(jīng)不值得花時(shí)間學(xué)習(xí)了,當(dāng)然了解一下也是可以的。如果你是一位萌新后端,不想了解jsp,或者想做一個(gè)前后端分離的項(xiàng)目,想在純html網(wǎng)頁(yè)上實(shí)現(xiàn)前后端交互,不妨看看這篇文章。
一、Q/A
1.什么是ajax
? 請(qǐng)自行谷歌/百度,反正我復(fù)制粘貼在這你也不會(huì)看。
2.ajax可以做什么
? 可以實(shí)現(xiàn)不刷新整個(gè)網(wǎng)頁(yè)來(lái)更新網(wǎng)頁(yè)的數(shù)據(jù),也可以直接拿來(lái)做前后端交互。
3.這里講的是是原生ajax實(shí)現(xiàn)嗎?后端是php還是Java?
? 不是,是jQuery的ajax實(shí)現(xiàn),后端是Java的SpringMVC框架。
三、前置知識(shí)要求
1.SpringMVC的基本了解
2.認(rèn)識(shí)基礎(chǔ)html的寫(xiě)法以及了解基本標(biāo)簽的作用
3.了解maven的使用
四、環(huán)境準(zhǔn)備
1.IDEA2019.3.1,JDK13
2.SpringMVC基本環(huán)境
注意xml配置文件中的攔截器設(shè)置,不要攔截html文件和js文件,如圖
<!-- 設(shè)置靜態(tài)資源不過(guò)濾 -->
<mvc:resources location="/css/" mapping="/css/**" />
<mvc:resources location="/images/" mapping="/images/**" />
<mvc:resources location="/js/" mapping="/js/**" />
<mvc:resources location="/html/" mapping="/html/**" />
3.建立一個(gè)前端頁(yè)面test.html 引入jQuery文件,可以去jQuery官網(wǎng)下載。
如圖,src里寫(xiě)jQuery文件的路徑
<head>
? ? <meta charset="UTF-8">
? ? <title>Title</title>
? ? <script src="../js/jquery.min.js"></script>
</head>
如果不想每次打開(kāi)tomcat都手動(dòng)輸入地址跳轉(zhuǎn)到test.html,可以在web.xml里寫(xiě)上
<welcome-file-list>
<welcome-file>test.html</welcome-file>
</welcome-file-list>
給一些缺乏前端知識(shí)的萌新后端講一些注意的點(diǎn):
(1)關(guān)于jquery.js和jquery.min.js的區(qū)別:官網(wǎng)可以下載jquery.js和jquery.min.js兩個(gè)文件的內(nèi)容是一樣的,不要認(rèn)為帶min的是簡(jiǎn)略版。帶min的js文件體積較小,因?yàn)閴嚎s了文件里多余的空格和換行符,但所有內(nèi)容擠在一起閱讀源碼困難,當(dāng)然作為初學(xué)者我們不看源碼因此下哪個(gè)都是可以的
(2)這個(gè)引用jquery包的<script>標(biāo)簽放在body中也可以,但如果放在body中的話應(yīng)該放在你寫(xiě)的代碼的<script>標(biāo)簽的最上面,以免需要用到函數(shù)時(shí)還沒(méi)有加載這個(gè)包。
(3)此外,引入jquery包的<script>標(biāo)簽內(nèi)部不要寫(xiě)你的js程序,在內(nèi)部寫(xiě)你的語(yǔ)句會(huì)失效,請(qǐng)另開(kāi)一個(gè)<script>標(biāo)簽
4.引入解析json的maven依賴,不引入會(huì)報(bào)415錯(cuò)誤,可以自己改一下版本。
<!--json-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
引入后記得在maven窗口點(diǎn)一下刷新,否則包引入不進(jìn)去

五、開(kāi)始教你寫(xiě)ajax
1.首先在body里寫(xiě)一個(gè)文本框和按鈕
<input id="txt" type="text">
<button id="btn" onclick="testajax()">點(diǎn)擊我</button>
意思是按鈕被點(diǎn)擊時(shí)執(zhí)行testajax()函數(shù)
2.接下來(lái)在<script>標(biāo)簽內(nèi)寫(xiě)一個(gè)叫testajax的函數(shù)
function testajax(){
? var text=document.getElementById("txt").value;
? $.ajax({
? type:"post",
? url:"test",
? contentType:"application/json;charset=UTF-8",
? data:JSON.stringify({
? "k":"123",
? ? "heihei":text
? }),
? //dataType:"json",
? success:function(data){
? ? alert("執(zhí)行成功!")
? }
});
}
3.講一下這段代碼,第一句var text=document.getElementById("txt").value;的意思是定義一個(gè)叫text的變量,JavaScript中的變量是不分類型的,一律用var定義,text的值等于什么呢?
docment.getElementById(“xxx”)是固定寫(xiě)法,意思是得到某個(gè)id為xxx的元素,由于輸入框的id是txt,因此我們就獲得了輸入框?!?value”的意思是這個(gè)輸入框里的內(nèi)容,也就是你給輸入框輸入的東西。當(dāng)然你也可以用jQuery里的選擇器,直接寫(xiě)$(“#txt”).value,效果是等同的。
然后我們向下看,$.ajax是固定寫(xiě)法,$是jQuery的縮寫(xiě),因此寫(xiě)jQuery.ajax效果是一樣的,意思是要用ajax了,注意寫(xiě)法,里面的值是被包裹在$.ajax({…});里面的,不能忘記最后的”;”標(biāo)點(diǎn)符號(hào)。
$ajax({…});里面包裹的是各種設(shè)置,設(shè)置之間用逗號(hào)隔開(kāi),最后一個(gè)屬性之后不需要加逗號(hào)。
type的意思是用什么方式發(fā)送數(shù)據(jù),此處我們使用post方式;
url是發(fā)送/接收ajax請(qǐng)求的路徑,一會(huì)兒我們會(huì)在controller里用@RequestMapping設(shè)置該路徑對(duì)應(yīng)的方法。
contentType是你要給后端發(fā)送什么格式的請(qǐng)求,這里我們?cè)O(shè)置json,并且設(shè)定編碼為UTF-8.
data是你要發(fā)送請(qǐng)求的內(nèi)容,用鍵值對(duì)(key-value)的方式表示。不同鍵值對(duì)之間用逗號(hào)隔開(kāi),同理最后一個(gè)鍵值對(duì)后面不需要加逗號(hào)。因?yàn)槲覀冃枰l(fā)送json,因此我們用JSON.stringfy()函數(shù)把里面的內(nèi)容變成json字符串。我們發(fā)送的第一對(duì)鍵值對(duì),key是”k”,value是”123”,我們發(fā)送的第二對(duì)鍵值對(duì),key是”heihei”,值是text。注意這里的text沒(méi)有被雙引號(hào)包裹,原因是這是我們之前定義的變量——輸入框中的內(nèi)容。
datatype是ajax從后端接收的數(shù)據(jù)的類型,這里我們?cè)O(shè)置為json,但是這里我們先注釋掉,原因后續(xù)再講
succes里是ajax請(qǐng)求成功后要執(zhí)行的函數(shù),括號(hào)里的變量起什么名字都可以,我起名為data,data里是從后端返回的json.
4.由于我們返回了兩對(duì)鍵值對(duì),我們把它封裝成一個(gè)對(duì)象。
在domain層創(chuàng)建TestDomain.java這個(gè)類,里面剛好是我們的兩個(gè)鍵值對(duì)的鍵:
public class TestDomain {
private String k;
private String heihei;
省略get/set方法……
省略toString方法……
}
5.然后我們?cè)赾ontroller層來(lái)寫(xiě)一個(gè)TestController.java這個(gè)類,如下
@Controller
public class TestController {
@RequestMapping("/test")
? ? public @ResponseBody String testAJAX(@RequestBody TestDomain t){
? ? ? ? System.out.println(t.getHeihei());
? ? ? ? System.out.println(t.getK());
? ? ? ? System.out.println(t);
? ? ? ? return "ok";
? ? }
}
@Controller和@RequestMapping注解不作解釋。
關(guān)于@ResponseBody,是為了把我們返回的數(shù)據(jù)轉(zhuǎn)化為json,同時(shí)如果你不加這個(gè)注解,return “ok”會(huì)被認(rèn)為是跳轉(zhuǎn)到ok這個(gè)路徑,因此使用了ajax后return就失去了重定向的功能。
@RequstBody用來(lái)把我們接收到的json封裝到TestDomain類中。
可是既然我們現(xiàn)在不需要返回?cái)?shù)據(jù),能不能把String改成void呢?答案是不可以的,ajax需要發(fā)送請(qǐng)求和接收請(qǐng)求兩個(gè)過(guò)程才可以視為請(qǐng)求成功,如果你改成void不返回任何東西給ajax是會(huì)報(bào)錯(cuò)的。當(dāng)然String改成int之類的隨便什么都是可以的。
return里可以隨便返回一個(gè)字符串,不一定得是“ok”;
6.運(yùn)行項(xiàng)目

點(diǎn)擊按鈕,我們可以看到它彈出窗口并且正確輸出了


沒(méi)有正確輸出的小伙伴請(qǐng)檢查一下自己的代碼,右鍵瀏覽器窗口,點(diǎn)擊檢查可以看看控制臺(tái)報(bào)了什么錯(cuò)
7.測(cè)試一下向前端傳值
我們把success函數(shù)里的alert(“執(zhí)行成功”);改成alert(data);看看結(jié)果如何,注意不要加引號(hào)

再運(yùn)行項(xiàng)目,點(diǎn)擊按鈕,可以看見(jiàn)彈窗變成了

說(shuō)明我們傳值成功
四、一些報(bào)錯(cuò)
1.“‘$’is undefined”,這是引入jquery的js文件失敗導(dǎo)致的,一些項(xiàng)目的路徑比較詭異,自己多研究一下;
2.“參數(shù)是必選項(xiàng)”,這是指定了要發(fā)送json類型的數(shù)據(jù)給后端,但是沒(méi)有通過(guò)JSON.stringfy()進(jìn)行轉(zhuǎn)換導(dǎo)致的;
3.415錯(cuò)誤,常見(jiàn)原因:沒(méi)有引入json的解析依賴,或者沒(méi)有設(shè)置contentType為“application/json”
4.找不到路徑,常見(jiàn)原因:url路徑寫(xiě)的不對(duì),比如路徑前面加了“/”之類的