spring+springMVC+mybatis的整合 part7

為了程序執(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ì)怎樣

Paste_Image.png

這個(gè)錯(cuò)誤的意思是
Request method 'POST' not supportedPOST方法不被允許
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ò)程中的控制器,
ModelAndViewHttp請(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ì)路徑可以這么做

Paste_Image.png

對(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集成之路

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末房午,一起剝皮案震驚了整個(gè)濱河市矿辽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郭厌,老刑警劉巖袋倔,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異沪曙,居然都是意外死亡奕污,警方通過(guò)查閱死者的電腦和手機(jī)萎羔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門液走,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人贾陷,你說(shuō)我怎么就攤上這事缘眶。” “怎么了髓废?”我有些...
    開(kāi)封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵巷懈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我慌洪,道長(zhǎng)顶燕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任冈爹,我火速辦了婚禮涌攻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘频伤。我一直安慰自己恳谎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布憋肖。 她就那樣靜靜地躺著因痛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪岸更。 梳的紋絲不亂的頭發(fā)上鸵膏,一...
    開(kāi)封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音怎炊,去河邊找鬼谭企。 笑死用僧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赞咙。 我是一名探鬼主播责循,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼攀操!你這毒婦竟也來(lái)了院仿?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤速和,失蹤者是張志新(化名)和其女友劉穎歹垫,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颠放,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡排惨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碰凶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片暮芭。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖欲低,靈堂內(nèi)的尸體忽然破棺而出辕宏,到底是詐尸還是另有隱情,我是刑警寧澤砾莱,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布瑞筐,位于F島的核電站,受9級(jí)特大地震影響腊瑟,放射性物質(zhì)發(fā)生泄漏聚假。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一闰非、第九天 我趴在偏房一處隱蔽的房頂上張望膘格。 院中可真熱鬧,春花似錦河胎、人聲如沸闯袒。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)政敢。三九已至,卻和暖如春胚迫,著一層夾襖步出監(jiān)牢的瞬間喷户,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工访锻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留褪尝,地道東北人闹获。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像河哑,于是被迫代替她去往敵國(guó)和親避诽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 優(yōu)雅的SpringMvc+Mybatis應(yīng)用(四) 轉(zhuǎn)眼間文章已經(jīng)到了第四期了璃谨。堅(jiān)持做一件事沙庐,確實(shí)是很難的。特別是...
    Clone丶記憶閱讀 5,040評(píng)論 19 23
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,317評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理佳吞,服務(wù)發(fā)現(xiàn)拱雏,斷路器,智...
    卡卡羅2017閱讀 134,714評(píng)論 18 139
  • 畫畫零基礎(chǔ)底扳,以前只會(huì)畫個(gè)別火柴小人铸抑,一直對(duì)自己沒(méi)有信心,沒(méi)有勇氣拿起畫筆衷模。忙于學(xué)習(xí)鹊汛,更是覺(jué)得畫畫是一件浪費(fèi)時(shí)間的事...
    Blue__Ocean閱讀 283評(píng)論 3 1
  • 這是我畫的原始版的思維導(dǎo)圖,不太好算芯,已經(jīng)讓助教老師指點(diǎn)過(guò)了柒昏,準(zhǔn)備再畫一張。
    雪凝心閱讀 2,873評(píng)論 0 0