為了程序執(zhí)行效率歌亲、數(shù)據(jù)完整性和程序健壯性剑按,我們的前端必須做對(duì)應(yīng)的基礎(chǔ)數(shù)據(jù)效驗(yàn)疾就,后端的控制器必須做所有需要的數(shù)據(jù)的效驗(yàn)。
前端數(shù)據(jù)效驗(yàn)我們使用js完成艺蝴,界面樣式是由CSS完成猬腰,網(wǎng)絡(luò)請(qǐng)求采用異步請(qǐng)求,具體的實(shí)現(xiàn)是使用的ajax完成猜敢。
js獲取web頁(yè)面數(shù)據(jù)統(tǒng)一使用標(biāo)簽的ID姑荷,格式為:$("#標(biāo)簽ID")
web頁(yè)面標(biāo)簽最好一個(gè)標(biāo)簽一行,這樣代碼看起來(lái)更加舒服
后端接口返回?cái)?shù)據(jù)為json缩擂,前端頁(yè)面解析json控制程序流轉(zhuǎn)
很多時(shí)候我們要先引入相關(guān)的輔助JS
數(shù)據(jù)檢驗(yàn)JS代碼
function checkLoginInfo() {
if ("" == $("#u").val()) {
$("#u").tips({
side: 2,
msg: '用戶名不得為空',
bg: '#AE81FF',
time: 3
});
$("#u").focus();
return false;
}
if ($("#p").val() == "") {
$("#p").tips({
side: 2,
msg: '密碼不得為空',
bg: '#AE81FF',
time: 3
});
$("#p").focus();
return false;
}
return true;
}
登錄的js代碼
function webLogin() {
if (checkLoginInfo()) {
var loginname = $("#u").val();
var password = $("#p").val();
$.ajax({
type: "POST",
url: '<%=request.getContextPath()%>/userAction/login',
data: {loginId: loginname, pwd: password},
dataType: 'json', //當(dāng)這里指定為json的時(shí)候鼠冕,獲取到了數(shù)據(jù)后會(huì)自動(dòng)解析的,只需要返回值.字段名稱 就可以了
cache: false,
success: function (data) {
if (data.code == 1) {
window.location.href = data.data.nextUrl; //拿到服務(wù)器返回的地址胯盯,然后進(jìn)行跳轉(zhuǎn)操作
//window.location.href = '<%=request.getContextPath()%>/mvc/home'; //跳轉(zhuǎn)到主頁(yè)*/
} else {
alert(data.msg);
$("#u").focus();
}
}
});
}
}
注冊(cè)的JS代碼
function webReg() {
if ($('#user').val() == "") {
$('#user').focus();
$("#user").tips({
side: 2,
msg: '用戶名不能為空',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#user').val().length < 4 || $('#user').val().length > 16) {
$('#user').focus();
$("#user").tips({
side: 2,
msg: '用戶名位6-16字符',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#name').val().length < 2
|| $('#name').val().length > 16
|| $('#name').val() == "") {
$('#name').focus();
$("#name").tips({
side: 2,
msg: '用戶姓名必須為4-16位字符',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#passwd').val().length < 6) {
$('#passwd').focus();
$("#passwd").tips({
side: 2,
msg: '密碼不能小于6位',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#passwd2').val() != $('#passwd').val()) {
$('#passwd2').focus();
$("#passwd2").tips({
side: 2,
msg: '兩次密碼不一致',
bg: '#AE81FF',
time: 3
});
return false;
}
var sqq = /^1[34578]\d{9}$/;
if (!sqq.test($('#phoneNumber').val())
|| $('#phoneNumber').val().length < 11
|| $('#phoneNumber').val().length > 14
|| $('#phoneNumber').val() == "") {
$('#phoneNumber').focus();
$("#phoneNumber").tips({
side: 2,
msg: '手機(jī)號(hào)不正確',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#sex').val() == "") {
$('#sex').focus();
$("#sex").tips({
side: 2,
msg: '性別不能為空',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#age').val() == "") {
$('#age').focus();
$("#age").tips({
side: 2,
msg: '年齡不能為空',
bg: '#AE81FF',
time: 3
});
return false;
}
var loginname = $("#user").val();
var password = $("#passwd").val();
var username = $("#name").val();
var cellNumber = $("#phoneNumber").val();
var sex = $("#sex").val();
var age = $("#age").val();
$.ajax({
type: "POST",
url: '<%=request.getContextPath()%>/userAction/reg',
data: {loginId: loginname, pwd: password, name: username, sex: sex, age: age, cellNumber: cellNumber},
dataType: 'json',
cache: false,
success: function (data) {
if (data.code == 1) {
window.location.href = data.data.nextUrl;
} else {
alert(data.msg);
$("#user").focus();
}
}
});
}
上面的注釋已經(jīng)能很明顯的看出我們的 前端效驗(yàn)懈费、網(wǎng)絡(luò)請(qǐng)求和js解析json,下面我們?cè)谇岸隧?yè)面中調(diào)用這個(gè)js博脑,如下:
<form action="" //此處必須刪掉form表單的地址
name="loginform"
accept-charset="utf-8"
id="login_form"
class="loginForm"
method="post">
<input type="hidden" name="did" value="0"/>
<input type="hidden" name="to" value="log"/>
<div class="uinArea" id="uinArea">
<label class="input-tips" for="u">帳號(hào):</label>
<div class="inputOuter" id="uArea">
<input type="text" id="u" name="loginId" class="inputstyle"/>
</div>
</div>
<div class="pwdArea" id="pwdArea">
<label class="input-tips" for="p">密碼:</label>
<div class="inputOuter" id="pArea">
<input type="password" id="p" name="pwd" class="inputstyle"/>
</div>
</div>
<div style="padding-left:50px;margin-top:20px;">
<input type="button"
id="btn_login"
value="登 錄"
onclick="webLogin();" //此處調(diào)用我們上面寫的js的登錄方法
style="width:150px;"
class="button_blue"/>
</div>
</form>
主要就是在onclick
中添加js函數(shù)
前端頁(yè)面:
FORM表單必須刪除action的值
input type="submit"
要改為input type="button"
前端頁(yè)面完成后憎乙,我們必須在后端接口處,做出對(duì)應(yīng)的修改趋厉,讓他符合我們前端的調(diào)用規(guī)則寨闹。
后端修改如下:
登錄接口,因?yàn)閖son數(shù)據(jù)外層一般都是Object類型君账,所以返回值必須是Object
如果之前返回的是ModelAndView
,現(xiàn)在要改為Object
錯(cuò)誤405
也許有人問(wèn)繁堡,如果我不改會(huì)怎樣
這個(gè)錯(cuò)誤的意思是
Request method 'POST' not supported
POST方法不被允許The method received in the request-line is known by the origin server but not supported by the target resource.
不支持接收這種類型的數(shù)據(jù)對(duì)于請(qǐng)求所標(biāo)識(shí)的資源,不允許使用請(qǐng)求行中所指定的方法
如果把POST
請(qǐng)求換成GET
請(qǐng)求可以嗎
答案是不可以的,因?yàn)榈卿浤阈枰獋鲾?shù)據(jù)到后臺(tái)椭蹄,所以你要用POST
把數(shù)據(jù)傳給后臺(tái)
在網(wǎng)上還有人說(shuō)是路徑問(wèn)題
不過(guò)使用絕對(duì)路徑是沒(méi)錯(cuò)的
<%=request.getContextPath()%>
是為了解決相對(duì)路徑的問(wèn)題闻牡,可返回站點(diǎn)的根路徑。
<%=request.getContextPath()%>/userAction/login
解決方法:
把返回的數(shù)據(jù)ModelAndView
,現(xiàn)在要改為Object
ModelAndView
就是一個(gè)map
集合
一旦Controller
處理完客戶請(qǐng)求绳矩,則返回ModelAndView
對(duì)象給DispatcherServlet
前端控制器罩润。ModelAndView
中包含了模型(Model)
和視圖(View)
從宏觀角度考慮,DispatcherServlet
是整個(gè)Web
應(yīng)用的控制器翼馆;
從微觀角度考慮割以,Controller
是單個(gè)Http
請(qǐng)求處理過(guò)程中的控制器,
ModelAndView
是Http
請(qǐng)求過(guò)程中返回的模型和視圖应媚。前端控制器返回的視圖可以是視圖的邏輯名严沥,或者實(shí)現(xiàn)了View
接口的對(duì)象。View
對(duì)象能夠渲染客戶響應(yīng)結(jié)果中姜。其中消玄,ModelAndView
中的模型能夠供渲染View
時(shí)使用。借助于Map
對(duì)象能夠存儲(chǔ)模型丢胚。
通過(guò)上面的重構(gòu)可以明白以下幾點(diǎn):
前端
js實(shí)現(xiàn)基本的數(shù)據(jù)效驗(yàn)翩瓜,發(fā)起網(wǎng)絡(luò)請(qǐng)求(具體實(shí)現(xiàn)用ajax),返回類型設(shè)置json能自動(dòng)解析携龟,獲取頁(yè)面控件兔跌,頁(yè)面控件調(diào)用js
js獲取解析后的json數(shù)據(jù)的值,進(jìn)行程序流轉(zhuǎn)控制
后端:
后端控制器必須申明骨宠,后端的地址必須配置浮定,每個(gè)地址返回的數(shù)據(jù)類型要匹配,返回json數(shù)據(jù)层亿,方法上面必須配置:@ResponseBody
可以使用工具類來(lái)方便開(kāi)發(fā)
關(guān)于在HTML里引入圖片桦卒,css等資源
一般采用相對(duì)路徑
獲取某個(gè)資源的相對(duì)路徑可以這么做
對(duì)資源點(diǎn)擊右鍵→
Copy Relative Path
獲取相對(duì)路徑
選取一個(gè)比較喜歡的后端主頁(yè),然后把對(duì)應(yīng)的資源放入到對(duì)應(yīng)的文件目錄(js匿又、css方灾、images等),需要新加入的資源如果在以前的目錄中沒(méi)有的話碌更,那么需要在里面進(jìn)行配置裕偿。比如說(shuō)這里加入了字體文件,那么現(xiàn)在需要先把字體文件指定目錄為:
static/font/
目錄指定后需要在Spring
的配置文件痛单,spring-web.xml
中配置靜態(tài)資源的目錄如下:
<mvc:resources mapping="/fonts/**" location="/static/fonts/"/>
有文件的信息上傳
關(guān)于文件上傳
前端寫完數(shù)據(jù)發(fā)送嘿棘,后端寫完controller后
還要在Spring的配置文件中添加文件的支持設(shè)置,不然無(wú)論如何都收不到文件(文件一直為null)
補(bǔ)充配置文件旭绒,spring-web.xml
新增配置如下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--下面設(shè)置的是上傳文件的最大大小-->
<property name="maxUploadSize" value="10000000"/>
</bean>
Spring
接收文件上傳時(shí)鸟妙,Controller
的具體方法的參數(shù)前面插入注解焦人,同時(shí)數(shù)據(jù)類型是MultipartFile
。
js進(jìn)行前端流程控制重父,后端接口隔離花椭,前后端解耦。
主要參考于大牛Clone丶記憶的SSM集成之路