jfinal與bootstrap的登錄跳轉(zhuǎn)實(shí)戰(zhàn)演習(xí)
前言:終于來(lái)了一篇有質(zhì)量的文章,我個(gè)人感覺(jué)非常不錯(cuò),《jfinal與bootstrap之間的登錄跳轉(zhuǎn)實(shí)戰(zhàn)》。具體內(nèi)容包含有點(diǎn)擊登錄彈出模態(tài)框、點(diǎn)擊登錄確認(rèn)按鈕后的validate、jfinal的validate、jfinal的session管理、ajax請(qǐng)求與返回信息處理、頁(yè)面間智能跳轉(zhuǎn)。
彈出模態(tài)框以及jquery validate可以參照jquery weebox總結(jié)、彈出窗口不居中顯示?、jquery validate初上手系列文章。
從jfinal的validate說(shuō)起
當(dāng)然你可以參考jfinal提供的幫助文檔,我當(dāng)然也必須是參照了官方文檔,當(dāng)然對(duì)于這種開(kāi)源技術(shù)每個(gè)人在使用的過(guò)程中肯定有千奇百態(tài)的問(wèn)題,那么依據(jù)我的實(shí)戰(zhàn)結(jié)果,我想再贅述一遍也是非常有必要的。
1.指定config中的路由
me.add("/login", MembersController.class, "/pages/login");
2.編寫(xiě)conroller類
public class MembersController extends BaseController { @Before(MembersValidator.class) @ActionKey("/login") public void login() { // 獲取用戶名 String name = getPara("username"); // 獲取密碼 String password = getPara("password"); Members mem = Members.me.getMemByNamePasswd(name, CipherUtils.generatePassword(password)); if (mem != null) { // 保存session getSession().setAttribute("username", name); // 最后登錄ip mem.set("lastip", getRequest().getRemoteHost()); mem.set("lastvisit", DateUtils.getCurrentTime()); mem.update(); ajaxDoneSuccess("登錄成功!"); } else { ajaxDoneError("用戶不存在!"); } // 跳轉(zhuǎn)到前臺(tái)發(fā)起請(qǐng)求的路徑 renderJson(); } }
注意:
使用before綁定validate
使用actionkey綁定前端請(qǐng)求action名
使用getSession().setAttribute來(lái)操作session,同時(shí)前端稍后介紹如何使用
封裝ajaxDone系列方法進(jìn)行數(shù)據(jù)格式綁定,前端稍后介紹
使用renderJson方法對(duì)ajax請(qǐng)求返回結(jié)果數(shù)據(jù)進(jìn)行json格式輸出
接下來(lái)你需要看看我封裝的baseController
3.BaseController
package com.hc.jf.controller; import com.jfinal.core.Controller; public class BaseController extends Controller { protected void ajaxDone(int statusCode, String message) { setAttr("statusCode", statusCode); setAttr("message", message); // 跳轉(zhuǎn)路徑 String forwardUrl = getPara("forwardUrl"); if (forwardUrl == null || forwardUrl.equals("")) { forwardUrl = getRequest().getRequestURL().toString(); } setAttr("forwardUrl", forwardUrl); setAttr("callbackType", getPara("callbackType")); } protected void ajaxDoneSuccess(String message) { ajaxDone(200, message); } protected void ajaxDoneInfo(String message) { ajaxDone(201, message); } protected void ajaxDoneSuccess(String message, String forwarUrl) { ajaxDone(200, message); } protected void ajaxDoneError(String message) { ajaxDone(300, message); } protected void ajaxDoneError(String message, String forwarUrl) { ajaxDone(300, message); } }
注意:
分別封裝成功、錯(cuò)誤、info級(jí)別的信息
增加了statusCode、message、forwardUrl、callbackType四個(gè)屬性。
以上兩個(gè)屬性和前端也有對(duì)應(yīng),稍后介紹。
4.MembersValidator
package com.hc.jf.validator; import com.hc.jf.entity.Members; import com.jfinal.core.Controller; import com.jfinal.validate.Validator; public class MembersValidator extends Validator { @Override protected void validate(Controller controller) { validateRequiredString("username", "usernameMsg", "請(qǐng)輸入用戶名!"); validateRequiredString("password", "passwordMsg", "請(qǐng)輸入密碼!"); } @Override protected void handleError(Controller controller) { controller.keepModel(Members.class); controller.render("login.jsp"); } }
注意:
這個(gè)validate確實(shí)沒(méi)什么屌用,因?yàn)榍岸艘呀?jīng)使用jquery validate進(jìn)行了check,然而請(qǐng)注意,如果你沒(méi)有使用jquery的或者為了網(wǎng)絡(luò)安全等等,有這個(gè)也不錯(cuò)。
好吧,我其實(shí)不想加入這個(gè)validate,但是我覺(jué)得可以我還沒(méi)有想到用處,但是心有戚戚焉,覺(jué)得它還是有用的。
jfinal的session管理
其實(shí)說(shuō)到這,已經(jīng)不是jfinal的session了,其實(shí)要說(shuō)的是前端。
<c:choose> <c:when test="${sessionScope.username!=null}"> <span> <a href="javascript:void(0);" id="mycenter" style=""> ${sessionScope.username}<s class="icon_arrow icon_arrow_down"></s> </a> <i class="line"></i> <a href="/logout" title="退出" id="user_login_out" style="padding: 0 6px;">退出</a> </span> </c:when> <c:otherwise> <span> <a title="登錄" href="javascript:show_pop_login();" id="show_pop_login">登錄</a> </span> </c:otherwise> </c:choose>
注意:
這里使用了${sessionScope.username}獲取session數(shù)據(jù),這只是很簡(jiǎn)單的一個(gè)應(yīng)用。
1中好像沒(méi)什么可說(shuō)的,但重要的是,你彈出登錄框后,需要重新回到對(duì)應(yīng)的跳轉(zhuǎn)頁(yè)面,然后顯示登錄的信息,好吧,我覺(jué)得沒(méi)有解釋清楚,那么上一張圖吧!
這個(gè)圖片為了商業(yè)機(jī)密,我只能截圖到這里了,哈哈。
就像很多互聯(lián)網(wǎng)網(wǎng)站一樣,你如果是游客的話,也可以打開(kāi)很多頁(yè)面進(jìn)行相關(guān)的信息進(jìn)行查看,比如你可以打開(kāi)1.html、2.html,但是這兩個(gè)頁(yè)面都可以點(diǎn)擊登錄按鈕彈出登錄框。那么問(wèn)題來(lái)了,你怎么保證從1.html打開(kāi)登錄的時(shí)候還跳轉(zhuǎn)到1.html,從2.html打開(kāi)登錄成功后還跳轉(zhuǎn)到2.html。
好吧,先說(shuō)到這,這里賣(mài)個(gè)關(guān)子,我們繼續(xù)看下個(gè)章節(jié)。
ajax請(qǐng)求與返回信息處理
1.彈出登錄窗口
/** * 彈出登錄框 */ function show_pop_login() { $.weeboxs.open(common.ctx + "/pages/login/login.jsp", { boxid : 'pop_user_login', contentType : 'ajax', showButton : false, showCancel : false, showOk : false, title : '會(huì)員登錄', width : 700, type : 'wee' }); }
這是彈出登錄框,至于weebox,你可以查看jquery weebox總結(jié)。
注意:
這里可能是從1.html打開(kāi)的,也可能是從2.html頁(yè)面打開(kāi)的登錄框。
2.然后我們?cè)賮?lái)看看登錄的form表單
<form class="pop_login_form" action="${ctx}/login?callbackType=closeCurrent" method="post" onsubmit="return validateCallback(this, dialogAjaxDone);"> <div class="row "> <div class="row"> <label class="col-md-4" style="margin-top: 10px;" for="name">用戶登錄</label> </div> <div class="form-group"> <div class="row"> <div class="col-md-2 col-md-offset-2 tr th"> <label for="name">賬戶</label> </div> <div class="col-md-5"> <input type="text" style="" class="form-control required" id="username" name="username" placeholder="請(qǐng)輸入會(huì)員編號(hào)" autocomplete="off"> </div> </div> </div> <div class="form-group"> <div class="row"> <div class="col-md-2 col-md-offset-2 tr th"> <label for="name">密碼</label> </div> <div class="col-md-5"> <input type="password" class="form-control required" id="password" name="password" placeholder="請(qǐng)輸入登陸密碼"> </div> </div> </div> <div class="row"> <div class="checkbox"> <label> <input type="checkbox"> 記住我(下次自動(dòng)登陸) </label> </div> </div> <div class="row"> <button type="submit" style="margin-bottom: 10px;" class="btn btn-default">提交</button> </div> </div> </form>
注意:
你需要關(guān)注action=”${ctx}/login?callbackType=closeCurrent”
再關(guān)注onsubmit=”return validateCallback(this, dialogAjaxDone);”
好吧,我們先來(lái)看看登錄的界面吧。
很漂亮的登錄框,漂亮的不像實(shí)力派!嘻嘻。
然后關(guān)鍵的部分來(lái)了,請(qǐng)繼續(xù)關(guān)注下節(jié),我把發(fā)送ajax請(qǐng)求也放在下節(jié)的代碼中,就省得重復(fù)。
頁(yè)面間智能跳轉(zhuǎn)
1.提交請(qǐng)求
/** * 普通ajax表單提交 * * @param {Object} * form * @param {Object} * callback * @param {String} * confirmMsg 提示確認(rèn)信息 */ function validateCallback(form, callback, confirmMsg) { var $form = $(form); if (!$form.valid()) { return false; } var _submitFn = function() { var forwardUrl = window.location.href; var formUrl = $form.attr("action"); if (formUrl.indexOf("?") != -1) { formUrl += "&forwardUrl=" + forwardUrl; } else { formUrl += "?forwardUrl=" + forwardUrl; } $.ajax({ type : form.method || 'POST', url : formUrl, data : $form.serializeArray(), dataType : "json", cache : false, success : callback || YUNM.ajaxDone, error : YUNM.ajaxError }); } if (confirmMsg) { alertMsg.confirm(confirmMsg, { okCall : _submitFn }); } else { _submitFn(); } return false; }
好吧,看到這,你也許會(huì)說(shuō)我剽竊了DWZ的靈感,OK,既然zhanghuihua同學(xué)開(kāi)源了,有必要我們就好好的利用是吧。
注意:
你看到了forwardUrl的相關(guān)代碼,沒(méi)錯(cuò),這個(gè)關(guān)鍵的字段就是來(lái)傳遞發(fā)起請(qǐng)求的頁(yè)面路徑,比如說(shuō)1.html,2.html。
然后,ajax執(zhí)行成功后,也就是登陸成功后,我們要執(zhí)行callback方法,也就是dialogAjaxDone方法,那么你需要繼續(xù)看下去。
2.回調(diào)函數(shù)
/** * dialog上的表單提交回調(diào)函數(shù) 服務(wù)器轉(zhuǎn)回forwardUrl,可以重新載入指定的頁(yè)面. * statusCode=YUNM.statusCode.ok表示操作成功, 自動(dòng)關(guān)閉當(dāng)前dialog */ function dialogAjaxDone(json) { YUNM.ajaxDone(json); if (json[YUNM.keys.statusCode] == YUNM.statusCode.ok || json[YUNM.keys.statusCode] == YUNM.statusCode.info) { if ("closeCurrent" == json.callbackType) { close_pop(); } // 如果指定了后調(diào)轉(zhuǎn)頁(yè)面,進(jìn)行調(diào)轉(zhuǎn) if (json.forwardUrl) { location.href = json.forwardUrl; } } } ajaxDone : function(json) { if (json[YUNM.keys.statusCode] == YUNM.statusCode.error) { if (json[YUNM.keys.message]) $.showErr(json[YUNM.keys.message]); ; } else if (json[YUNM.keys.statusCode] == YUNM.statusCode.timeout) { alertMsg.error(json[YUNM.keys.message]); } },
注意:
第二串代碼就是出于錯(cuò)誤消息,諸如“用戶不存在的”,還有timeout。
第一串代碼就是回調(diào)函數(shù),其作用就是成功后關(guān)閉彈出框,然后再跳轉(zhuǎn)到對(duì)應(yīng)頁(yè)面。
結(jié)語(yǔ):OK,這樣一篇文章希望能夠給熱愛(ài)jfinal和bootstrap的同學(xué)帶來(lái)靈感!
- JFinal使用ajaxfileupload實(shí)現(xiàn)圖片上傳及預(yù)覽
- JFinal實(shí)現(xiàn)偽靜態(tài)的方法
- JFinal極速開(kāi)發(fā)框架使用筆記分享
- jfinal與bootstrap的登出實(shí)戰(zhàn)詳解
- java 中JFinal getModel方法和數(shù)據(jù)庫(kù)使用出現(xiàn)問(wèn)題解決辦法
- Bootstrap+jfinal退出系統(tǒng)彈出確認(rèn)框的實(shí)現(xiàn)方法
- Bootstrap+jfinal實(shí)現(xiàn)省市級(jí)聯(lián)下拉菜單
- jfinal添加jcaptcha驗(yàn)證碼實(shí)現(xiàn)方法
- Java中JFinal框架動(dòng)態(tài)切換數(shù)據(jù)庫(kù)的方法
相關(guān)文章
解讀CocosCreator源碼之引擎啟動(dòng)與主循環(huán)
這篇文章主要介紹了CocosCreator源碼解讀之引擎啟動(dòng)與主循環(huán),對(duì)CocosCreator感興趣的同學(xué),可以研究參考一下2021-04-04js中判斷一個(gè)數(shù)是不是素?cái)?shù)的三種方法例子
這篇文章主要給大家介紹了關(guān)于js中如何判斷一個(gè)數(shù)是不是素?cái)?shù)的三種方法,素?cái)?shù)(只能被1和本身整除的數(shù))規(guī)律:把這個(gè)數(shù)除以它之前的每一個(gè)數(shù)(從2開(kāi)始)只要找到一個(gè)整除(余數(shù)為0)就是非素?cái)?shù),需要的朋友可以參考下2023-10-109個(gè)讓JavaScript調(diào)試更簡(jiǎn)單的Console命令
這篇文章主要為大家詳細(xì)介紹了9個(gè)讓JavaScript調(diào)試更簡(jiǎn)單的Console命令,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11JavaScript中運(yùn)算符規(guī)則和隱式類型轉(zhuǎn)換示例詳解
JavaScript中運(yùn)算符規(guī)則的隱式類型轉(zhuǎn)換是什么? 這是每個(gè)學(xué)習(xí)Javascript的新手們都應(yīng)該知道的一個(gè)問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于JavaScript中運(yùn)算符規(guī)則和隱式類型轉(zhuǎn)換的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-09-09javascript 中select框觸發(fā)事件過(guò)程的分析
這篇文章主要介紹了javascript 中select框觸發(fā)事件過(guò)程的分析的相關(guān)資料,這里對(duì)select 觸發(fā)過(guò)程進(jìn)行了深入分析,幫助大家理解這部分內(nèi)容,需要的朋友可以參考下2017-08-08詳解cesium實(shí)現(xiàn)大批量POI點(diǎn)位聚合渲染優(yōu)化方案
這篇文章主要為大家介紹了cesium實(shí)現(xiàn)大批量POI點(diǎn)位聚合渲染優(yōu)化方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05ligerUI---ListBox(列表框可移動(dòng)的實(shí)例)
下面小編就為大家分享一篇ligerUI---ListBox(列表框可移動(dòng)的實(shí)例),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-11-11微信小程序使用onreachBottom實(shí)現(xiàn)頁(yè)面觸底加載及分頁(yè)效果
小程序還沒(méi)有使用pc端的那種分頁(yè)格式,下面這篇文章主要給大家介紹了關(guān)于微信小程序使用onreachBottom實(shí)現(xiàn)頁(yè)面觸底加載及分頁(yè)效果的相關(guān)資料,需要的朋友可以參考下2022-10-10