前言:終于來了一篇有質量的文章,我個人感覺非常不錯,《jfinal與bootstrap之間的登錄跳轉實戰(zhàn)》。具體內容包含有點擊登錄彈出模態(tài)框、點擊登錄確認按鈕后的validate、jfinal的validate、jfinal的session管理、ajax請求與返回信息處理、頁面間智能跳轉。
彈出模態(tài)框以及jQuery validate可以參照jquery weebox總結、彈出窗口不居中顯示?、jquery validate初上手系列文章。
從jfinal的validate說起
當然你可以參考jfinal提供的幫助文檔,我當然也必須是參照了官方文檔,當然對于這種開源技術每個人在使用的過程中肯定有千奇百態(tài)的問題,那么依據我的實戰(zhàn)結果,我想再贅述一遍也是非常有必要的。
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("用戶不存在!");
}
// 跳轉到前臺發(fā)起請求的路徑
renderJson();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
注意:
- 使用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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
注意:
- 分別封裝成功、錯誤、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");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
注意:
- 這個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中好像沒什么可說的,但重要的是,你彈出登錄框后,需要重新回到對應的跳轉頁面,然后顯示登錄的信息,好吧,我覺得沒有解釋清楚,那么上一張圖吧!

這個圖片為了商業(yè)機密,我只能截圖到這里了,哈哈。
就像很多互聯網網站一樣,你如果是游客的話,也可以打開很多頁面進行相關的信息進行查看,比如你可以打開1.html、2.html,但是這兩個頁面都可以點擊登錄按鈕彈出登錄框。那么問題來了,
你怎么保證從1.html打開登錄的時候還跳轉到1.html,從2.html打開登錄成功后還跳轉到2.html。
好吧,先說到這,這里賣個關子,我們繼續(xù)看下個章節(jié)。
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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
注意:
- 你需要關注action=”${ctx}/login?callbackType=closeCurrent”
- 再關注onsubmit=”return validateCallback(this, dialogAjaxDone);”
好吧,我們先來看看登錄的界面吧。

很漂亮的登錄框,漂亮的不像實力派!嘻嘻。
然后關鍵的部分來了,請繼續(xù)關注下節(jié),我把發(fā)送ajax請求也放在下節(jié)的代碼中,就省得重復。
頁面間智能跳轉
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
好吧,看到這,你也許會說我剽竊了DWZ的靈感,OK,既然zhanghuihua同學開源了,有必要我們就好好的利用是吧。
注意:
- 你看到了forwardUrl的相關代碼,沒錯,這個關鍵的字段就是來傳遞發(fā)起請求的頁面路徑,比如說1.html,2.html。
- 然后,ajax執(zhí)行成功后,也就是登陸成功后,我們要執(zhí)行callback方法,也就是dialogAjaxDone方法,那么你需要繼續(xù)看下去。
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的同學帶來靈感!
|