前言:终于来了一篇有质量的文章,我个人感觉非常不错,《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" > ${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" 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的同学带来灵感!