前言:終於來了一篇有質量的文章,我個人感覺非常不錯,《jfinal與bootstrap之間的登錄跳轉實戰》。具體內容包含有點擊登錄彈出模態框、點擊登錄確認按鈕後的validate、jfinal的validate、jfinal的session管理、ajax請求與返回信息處理、頁面間智能跳轉。
彈出模態框以及jquery validate可以參照jquery weebox總結、彈出窗口不居中顯示?、jquery validate初上手系列文章。
從jfinal的validate說起
當然你可以參考jfinal提供的幫助文檔,我當然也必須是參照了官方文檔,當然對於這種開源技術每個人在使用的過程中肯定有千奇百態的問題,那麼依據我的實戰結果,我想再贅述一遍也是非常有必要的。
1.指定config中的路由
me.add("/login", MembersController.class, "/pages/login");
2.編寫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("用戶不存在!"); } // 跳轉到前台發起請求的路徑 renderJson(); } }
注意:
使用before綁定validate
使用actionkey綁定前端請求action名
使用getSession().setAttribute來操作session,同時前端稍後介紹如何使用
封裝ajaxDone系列方法進行數據格式綁定,前端稍後介紹
使用renderJson方法對ajax請求返回結果數據進行json格式輸出
接下來你需要看看我封裝的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); // 跳轉路徑 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); } }
注意:
分別封裝成功、錯誤、info級別的信息
增加了statusCode、message、forwardUrl、callbackType四個屬性。
以上兩個屬性和前端也有對應,稍後介紹。
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", "請輸入用戶名!"); validateRequiredString("password", "passwordMsg", "請輸入密碼!"); } @Override protected void handleError(Controller controller) { controller.keepModel(Members.class); controller.render("login.jsp"); } }
注意:
這個validate確實沒什麼屌用,因為前端已經使用jquery validate進行了check,然而請注意,如果你沒有使用jquery的或者為了網絡安全等等,有這個也不錯。
好吧,我其實不想加入這個validate,但是我覺得可以我還沒有想到用處,但是心有戚戚焉,覺得它還是有用的。
jfinal的session管理
其實說到這,已經不是jfinal的session了,其實要說的是前端。
<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數據,這只是很簡單的一個應用。
1中好像沒什麼可說的,但重要的是,你彈出登錄框後,需要重新回到對應的跳轉頁面,然後顯示登錄的信息,好吧,我覺得沒有解釋清楚,那麼上一張圖吧!
這個圖片為了商業機密,我只能截圖到這裡了,哈哈。
就像很多互聯網網站一樣,你如果是游客的話,也可以打開很多頁面進行相關的信息進行查看,比如你可以打開1.html、2.html,但是這兩個頁面都可以點擊登錄按鈕彈出登錄框。那麼問題來了,你怎麼保證從1.html打開登錄的時候還跳轉到1.html,從2.html打開登錄成功後還跳轉到2.html。
好吧,先說到這,這裡賣個關子,我們繼續看下個章節。
ajax請求與返回信息處理
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 : '會員登錄', width : 700, type : 'wee' }); }
這是彈出登錄框,至於weebox,你可以查看jquery weebox總結。
注意:
這裡可能是從1.html打開的,也可能是從2.html頁面打開的登錄框。
2.然後我們再來看看登錄的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="請輸入會員編號" 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="請輸入登陸密碼"> </div> </div> </div> <div class="row"> <div class="checkbox"> <label> <input type="checkbox"> 記住我(下次自動登陸) </label> </div> </div> <div class="row"> <button type="submit" style="margin-bottom: 10px;" class="btn btn-default">提交</button> </div> </div> </form>
注意:
你需要關注action=”${ctx}/login?callbackType=closeCurrent”
再關注onsubmit=”return validateCallback(this, dialogAjaxDone);”
好吧,我們先來看看登錄的界面吧。
很漂亮的登錄框,漂亮的不像實力派!嘻嘻。
然後關鍵的部分來了,請繼續關注下節,我把發送ajax請求也放在下節的代碼中,就省得重復。
頁面間智能跳轉
1.提交請求
/** * 普通ajax表單提交 * * @param {Object} * form * @param {Object} * callback * @param {String} * confirmMsg 提示確認信息 */ 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; }
好吧,看到這,你也許會說我剽竊了DWZ的靈感,OK,既然zhanghuihua同學開源了,有必要我們就好好的利用是吧。
注意:
你看到了forwardUrl的相關代碼,沒錯,這個關鍵的字段就是來傳遞發起請求的頁面路徑,比如說1.html,2.html。
然後,ajax執行成功後,也就是登陸成功後,我們要執行callback方法,也就是dialogAjaxDone方法,那麼你需要繼續看下去。
2.回調函數
/** * dialog上的表單提交回調函數 服務器轉回forwardUrl,可以重新載入指定的頁面. * statusCode=YUNM.statusCode.ok表示操作成功, 自動關閉當前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(); } // 如果指定了後調轉頁面,進行調轉 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]); } },
注意:
第二串代碼就是出於錯誤消息,諸如“用戶不存在的”,還有timeout。
第一串代碼就是回調函數,其作用就是成功後關閉彈出框,然後再跳轉到對應頁面。
結語:OK,這樣一篇文章希望能夠給熱愛jfinal和bootstrap的同學帶來靈感!