欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring shiro + bootstrap + jquery.validate 实现登录、注册功能

程序员文章站 2024-01-31 13:45:34
之前的文章中我们已经搭建好框架,并且设计好了,数据库。 现在我们开始实现登录功能,这个可以说是web应用最最最普遍的功能了。 先来说说我们登录的逻辑: 输入用户名、密...

之前的文章中我们已经搭建好框架,并且设计好了,数据库。

现在我们开始实现登录功能,这个可以说是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啦!

Spring shiro + bootstrap + jquery.validate 实现登录、注册功能
Spring shiro + bootstrap + jquery.validate 实现登录、注册功能

其中还使用到啦jquery-confirm.js,这是一个弹出框的插件:

源码地址:

以上所述是小编给大家介绍的spring shiro + bootstrap + jquery.validate 实现登录、注册功能,希望对大家有所帮助