前言:终于来了一篇有质量的文章,我个人感觉非常不错,《jfinal与bootstrap之间的登录跳转实战》。具体内容包含有点击登录弹出模态框、点击登录确认按钮后的validate、jfinal的validate、jfinal的session管理、ajax请求与返回信息处理、页面间智能跳转。
弹出模态框以及jquery validate可以参照jquery weebox总结、弹出窗口不居中显示?、jquery 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();
}
}
注意:
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);
}
}
注意:
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");
}
}
注意:
其实说到这,已经不是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>
注意:
这个图片为了商业机密,我只能截图到这里了,哈哈。
就像很多互联网网站一样,你如果是游客的话,也可以打开很多页面进行相关的信息进行查看,比如你可以打开1.html、2.html,但是这两个页面都可以点击登录按钮弹出登录框。那么问题来了,
你怎么保证从1.html打开登录的时候还跳转到1.html,从2.html打开登录成功后还跳转到2.html。
好吧,先说到这,这里卖个关子,我们继续看下个章节。
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>
注意:
很漂亮的登录框,漂亮的不像实力派!嘻嘻。
然后关键的部分来了,请继续关注下节,我把发送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同学开源了,有必要我们就好好的利用是吧。
注意:
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]);
}
},
注意:
结语:OK,这样一篇文章希望能够给热爱jfinal和bootstrap的同学带来灵感!