Spring shiro + bootstrap + jquery.validate 实现登录、注册功能
之前的文章中我们已经搭建好框架,并且设计好了,数据库。
现在我们开始实现登录功能,这个可以说是web应用最最最普遍的功能了。
先来说说我们登录的逻辑:
输入用户名、密码(validate进行前端验证)——ajax调用后台action方法——根据用户名调用业务层到数据层查询数据库信息——查询的密码跟用户输入的密码比对——shiro登录身份验证——将用户信息存入session——响应前端——前端跳转
这个是我要告诉大家的姿势,还有很多很多的姿势。下面我们来看具体的代码。
首先前端验证,这里使用了jquery.validate来进行验证,jquery.validate的使用很简单,这里我们说说存js的方式:
$().ready(function() { /**登录验证**/ $("#login_form").validate({ rules: { loginaccount: "required", loginpass: { required: true, minlength: 5 }, }, messages: { loginaccount: "请输入姓名", loginpass: { required: "请输入密码", minlength: jquery.format("密码不能小于{0}个字 符") }, }, submithandler:function(form){ $.ajax({ datatype : "json", url : "sysuser/login.action", type : "post", data : $("#login_form").serialize(), success : function(data) { $.alert(data.message); if(data.success){ window.location.href = 'page/main.action'; } }, error : function (e){ var d = e.responsejson; if(d){ $.alert(d.message); } } }); return false; //阻止form提交 } }); /**注册验证**/ $("#register_form").validate({ rules: { loginaccount:{ required:true, remote: { url: "sysuser/getusernamecount.action", type: "post", datatype: "json", data: { loginaccount: function () { return $("#register_account").val(); } }, datafilter: function (data) { //判断控制器返回的内容 data = jquery.parsejson(data); return data.success; } } }, loginpass: { required: true, minlength: 5, maxlength:20 }, rloginpass: { equalto: "#register_password" }, useremail: { required: true, email: true, remote: { url: "sysuser/getemailcount.action", type: "post", datatype: "json", data: { email: function () { return $("#register_email").val(); } }, datafilter: function (data) { //判断控制器返回的内容 data = jquery.parsejson(data); return data.success; } } } }, messages: { loginaccount:{ required: "请输入姓名", remote: "用户名已存在" }, loginpass: { required: "请输入密码", minlength: jquery.format("密码不能小于{0}个字 符"), maxlength: jquery.format("密码不能大于{0}个字 符"), }, rloginpass: { required: "请输入确认密码", equalto: "两次密码不一样" }, useremail: { required: "请输入邮箱", email: "请输入有效邮箱", remote: "邮箱已存在" } }, submithandler:function(form){ $.ajax({ datatype : "json", url : "sysuser/register.action", type : "post", data : $("#register_form").serialize(), success : function(data) { $.alert(data.message); if(data.success){ window.location.href = 'page/main.action'; } }, error : function (e){ var d = e.responsejson; if(d){ $.alert(d.message); } } }); return false; //阻止form提交 } }); /**隐藏显示登录注册**/ $("#register_btn").click(function() { $("#register_form").css("display", "block"); $("#login_form").css("display", "none"); }); $("#back_btn").click(function() { $("#register_form").css("display", "none"); $("#login_form").css("display", "block"); }); });
html页面:
<%@ page language="java" import="java.util.*" pageencoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <c:set var="contextpath" value="${pagecontext.request.contextpath}"></c:set> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>主页</title> <!-- bootstrap core css --> <link href="${contextpath }/static/bootstrap/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet"> <link href="${contextpath }/static/bootstrap/css/font-awesome.min.css" rel="external nofollow" rel="stylesheet"> <link href="${contextpath }/static/alert/jquery-confirm.min.css" rel="external nofollow" rel="stylesheet"> <style type="text/css"> body { background: url(${contextpath }/static/img/login/bg.jpg) no-repeat; background-size: cover; font-size: 16px; } .form { background: rgba(255, 255, 255, 0.2); width: 400px; margin: 100px auto; } #login_form { display: block; } #register_form { display: none; } .fa { display: inline-block; top: 27px; left: 6px; position: relative; color: #ccc; } input[type="text"], input[type="password"] { padding-left: 26px; } .checkbox { padding-left: 21px; } </style> <!-- html5 shim and respond.js for ie8 support of html5 elements and media queries --> <!--[if lt ie 9]> <script src="${contextpath }/static/bootstrap/html5shiv/html5shiv.js"></script> <script src="${contextpath }/static/bootstrap/respond/respond.min.js"></script> <![endif]--> </head> <body> <div class="container"> <div class="form row"> <form class="form-horizontal col-sm-offset-3 col-md-offset-3" id="login_form"> <h3 class="form-title">登录</h3> <div class="col-sm-9 col-md-9"> <div class="form-group"> <i class="fa fa-user fa-lg"></i> <input class="form-control required" type="text" placeholder="请输入账号" name="loginaccount" autofocus="autofocus" maxlength="20" /> </div> <div class="form-group"> <i class="fa fa-lock fa-lg"></i> <input class="form-control required" type="password" placeholder="请输入密码" name="loginpass" maxlength="8" /> </div> <div class="form-group"> <label class="checkbox"> <input type="checkbox" name="rememberme" value="1" /> 记住我 </label> <hr /> <a href="javascript:;" rel="external nofollow" id="register_btn" class="">注册?</a> </div> <div class="form-group"> <input type="submit" class="btn btn-success pull-right" value="登录 " /> </div> </div> </form> </div> <div class="form row"> <form class="form-horizontal col-sm-offset-3 col-md-offset-3" id="register_form"> <h3 class="form-title">注册</h3> <div class="col-sm-9 col-md-9"> <div class="form-group"> <i class="fa fa-user fa-lg"></i> <input class="form-control required" type="text" placeholder="请输入账号" name="loginaccount" autofocus="autofocus" id="register_account" /> </div> <div class="form-group"> <i class="fa fa-lock fa-lg"></i> <input class="form-control required" type="password" placeholder="请输入密码" id="register_password" name="loginpass" /> </div> <div class="form-group"> <i class="fa fa-check fa-lg"></i> <input class="form-control required" type="password" placeholder="请输入确认密码" name="rloginpass" /> </div> <div class="form-group"> <i class="fa fa-envelope fa-lg"></i> <input class="form-control eamil" type="text" placeholder="email" name="useremail" id="register_email"/> </div> <div class="form-group"> <input type="submit" class="btn btn-success pull-right" value="注册" /> <input type="submit" class="btn btn-info pull-left" id="back_btn" value="返回" /> </div> </div> </form> </div> </div> <script type="text/javascript" src="${contextpath }/static/jquery/jquery.min.js"></script> <script type="text/javascript" src="${contextpath }/static/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="${contextpath }/static/alert/jquery-confirm.min.js" ></script> <script type="text/javascript" src="${contextpath }/static/jquery/jquery.validate.min.js" ></script> <script type="text/javascript" src="${contextpath }/static/login/login.js" ></script> </body> </html>
在$("#login_form").validate({...})
方法中,login_form为你要验证的form的id;rules为要验证的字段;messages为要提示的内容,如果不填写,则会提示默认信息;submithandler为点击提交(submit)按钮后的回调方法,这里面最后的return false是为了阻止form表单的提交,因为我这里要用ajax的方式提交;在注册中的loginaccount字段有一个属性remote这个是为了做ajax验证的,在没有提交表单之前,我们就验证用户输入的用户名是否在系统中已经存在。
我们在编程总,发现总是会有那么几个方法在相同的代码层总用到,比如在控制层中获取用户session,或者输出响应信息等;在dao层中调用hibernate的save方法,update方法,delete方法等。所以我们应该在框架搭建的初期去建立一些通用的工具类或者是base方法,下面我们新建basecontroller方法,并且让后面的控制器都来继承它。
import java.io.ioexception; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import javax.servlet.http.httpsession; import org.springframework.web.bind.annotation.modelattribute; import com.fasterxml.jackson.core.jsonencoding; import com.fasterxml.jackson.core.jsonfactory; import com.fasterxml.jackson.core.jsongenerator; import com.fasterxml.jackson.databind.objectmapper; import yfkj.gz.task.entity.sysuser; import yfkj.gz.task.util.result; /** * 父类控制器 * @author 胡汉三 * @date 2017年1月9日 下午5:23:52 */ @suppresswarnings("deprecation") public class basecontroller{ public static final string user_session = "user_session"; protected static objectmapper mapper = new objectmapper(); protected static jsonfactory factory = mapper.getjsonfactory(); protected static result result = new result(); protected httpservletrequest request; protected httpservletresponse response; protected httpsession session; @modelattribute public void setreqandres(httpservletrequest request, httpservletresponse response){ this.request = request; this.response = response; this.session = request.getsession(); } /**将json字符串输出**/ protected void writejson(string json) throws ioexception { response.setcontenttype("text/html;charset=utf-8"); response.getwriter().write(json); } /**将对象转成json输出**/ protected void writejson(object obj) throws ioexception { response.setcontenttype("text/html;charset=utf-8"); jsongenerator responsejsongenerator = factory.createjsongenerator(response.getoutputstream(), jsonencoding.utf8); responsejsongenerator.writeobject(obj); } /** * 获得session用户对象 * @return */ protected sysuser getuser(){ object userobj = session.getattribute(user_session); if(userobj == null){ return null; } return (sysuser)userobj; } }
用户的控制器sysusercontroller:
package yfkj.gz.task.controller; import java.io.ioexception; import java.util.date; import java.util.list; import javax.annotation.resource; import org.apache.shiro.securityutils; import org.apache.shiro.authc.usernamepasswordtoken; import org.apache.shiro.crypto.hash.sha256hash; import org.apache.shiro.subject.subject; import org.springframework.stereotype.controller; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.requestmethod; import yfkj.gz.task.entity.sysrole; import yfkj.gz.task.entity.sysuser; import yfkj.gz.task.service.isysroleservice; import yfkj.gz.task.service.isysuserservice; import yfkj.gz.task.util.dateutil; import yfkj.gz.task.util.stringutils; import yfkj.gz.support.btview; import yfkj.gz.support.controller.basecontroller; /** * 用户控制器 * @author 胡汉三 * @date 2017年1月16日 下午2:31:39 */ @controller @requestmapping("/sysuser") public class sysusercontroller extends basecontroller{ @resource private isysuserservice userservice; @resource private isysroleservice roleservice; /** * 分页查询用户 * @param response * @param user * @param btview * @throws ioexception */ @requestmapping(value = "/finduser", method = { requestmethod.post, requestmethod.get }) public void finduser(sysuser user,btview<sysuser> btview) throws ioexception{ list<sysuser> list = userservice.findsysuserpage(btview, null); btview.setrows(list); super.writejson(btview); } /** * 用户登录 * @param response * @param user * @throws ioexception */ @requestmapping(value = "/login", method = { requestmethod.post, requestmethod.get }) public void login(sysuser user,boolean rememberme) throws ioexception{ //用户登录 sysuser userinfo = userservice.getbyproerties(new string[]{"loginaccount"}, new string[]{user.getloginaccount()},null); if(userinfo==null){ result.setmessage("用户名错误"); super.writejson(result); return; } if(!userinfo.getloginpass().equals(new sha256hash(user.getloginpass()).tohex())){ result.setmessage("密码错误"); super.writejson(result); return; } //存入session subject subject = securityutils.getsubject(); //记得传入明文密码 subject.login(new usernamepasswordtoken(userinfo.getloginaccount(), user.getloginpass(), rememberme)); session.setattribute(user_session, userinfo); result.setmessage("登录成功"); result.setsuccess(true); super.writejson(result); } /** * 用户注册 * @param response * @param user * @throws ioexception */ @requestmapping(value = "/register", method = { requestmethod.post, requestmethod.get }) public void register(sysuser user) throws ioexception{ long count = userservice.getcountbyproerties(new string[]{"loginaccount"}, new string[]{user.getloginaccount()}); if(count>0){ result.setmessage("账号已存在"); super.writejson(result); return; } long countemail = userservice.getcountbyproerties(new string[]{"useremail"}, new string[]{user.getuseremail()}); if(countemail>0){ result.setmessage("邮箱已存在"); super.writejson(result); return; } try{ //注册时间 user.setregistertime(dateutil.getdatetime(new date())); //sha256hash加密 user.setloginpass(new sha256hash(user.getloginpass()).tohex()); //默认为注册用户 sysrole role = roleservice.getbyproerties(new string[]{"rolekey"},new string[]{"role_user"},null); user.getroles().add(role); userservice.save(user); //存入session subject subject = securityutils.getsubject(); subject.login(new usernamepasswordtoken(user.getloginaccount(), user.getloginpass())); session.setattribute(user_session, user); result.setmessage("注册成功"); result.setsuccess(true); }catch(exception e){ result.setmessage("注册失败"); } super.writejson(result); } /** * 判断用户账号是否已存在 * @param response * @param user * @throws ioexception */ @requestmapping(value = "/getusernamecount", method = { requestmethod.post, requestmethod.get }) public void getusernamecount(string loginaccount) throws ioexception{ result.setsuccess(false); if(stringutils.isblank(loginaccount)){ result.setmessage("账号不能为空"); super.writejson(result); return; } long count = userservice.getcountbyproerties(new string[]{"loginaccount"}, new string[]{loginaccount}); if(count>0){ result.setmessage("账号已存在"); }else{ result.setsuccess(true); result.setmessage("该账号可用"); } super.writejson(result); } /** * 判断用户邮箱是否已存在 * @param response * @param email * @throws ioexception */ @requestmapping(value = "/getemailcount", method = { requestmethod.post, requestmethod.get }) public void getemailcount(string email) throws ioexception{ result.setsuccess(false); if(stringutils.isblank(email)){ result.setmessage("邮箱不能为空"); super.writejson(result); return; } long count = userservice.getcountbyproerties(new string[]{"useremail"}, new string[]{email}); if(count>0){ result.setmessage("邮箱已存在"); }else{ result.setsuccess(true); result.setmessage("该邮箱可用"); } super.writejson(result); } // 登出 @requestmapping("/logout") public void logout() throws ioexception { //退出权限验证 securityutils.getsubject().logout(); //销毁session session.invalidate(); response.sendredirect(request.getcontextpath()+"/login.jsp"); } }
至此,登录跟注册就ok啦!
其中还使用到啦jquery-confirm.js,这是一个弹出框的插件:
源码地址:
以上所述是小编给大家介绍的spring shiro + bootstrap + jquery.validate 实现登录、注册功能,希望对大家有所帮助
推荐阅读
-
Spring MVC+mybatis实现注册登录功能
-
Spring+MongoDB实现登录注册功能
-
Spring MVC+mybatis实现注册登录功能
-
Spring+MongoDB实现登录注册功能
-
Spring Boot实现qq邮箱验证码注册和登录验证功能
-
PHP实现登录注册之BootStrap表单功能
-
PHP 结合 Bootstrap 实现学生列表以及添加学生功能实现(继上篇登录及注册功能之后)
-
Spring shiro + bootstrap + jquery.validate 实现登录、注册功能
-
Spring shiro bootstrap jquery.validate 登录、注册功能的实现方法
-
Spring Boot实现qq邮箱验证码注册和登录验证功能