之前的文章中我們已經搭建好框架,并且設計好了,數據庫。
現在我們開始實現登錄功能,這個可以說是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,這是一個彈出框的插件:點擊查看
源碼地址:https://git.oschina.net/gzsjd/task
以上所述是小編給大家介紹的Spring shiro + bootstrap + jquery.validate 實現登錄、注冊功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
新聞熱點
疑難解答