一.實現登錄驗證的步驟
這次的小demo,采用的是MVC分層模式進行練習,所以我們從M->C->V開始編寫代碼,先完成與數據庫交互的Dao層,然后再到service和servlet層,最后是界面HTMl的實現。
二.dao層的實現
dao層的實現較簡單,就是將操作數據庫的SQL語句傳到數據庫,並返回想要的信息,這里我們要實現登錄驗證,就要通過用戶名去查詢數據了有不有這個用戶,如果有就返回一個User(用戶)對象,所以我們要寫一個用戶的實體類。
public class User { private int id; private String name; private String password; /*get、set方法*/ }
然后我們編寫Dao層代碼,這里我用到了接口interface,它的好處是讓你的代碼更有規范性,代碼管理起來簡單方便,易於維護,擴展性強
//接口
public interface UserDao { public User findByName(String username);//通過名字查用戶 }
//實現接口 public class UserDaoImpl implements UserDao { /** * 通過賬戶名查詢賬戶 */ @Override public User findByName(String username) { // TODO Auto-generated method stub Connection conn = JDBCUtils_Oracle.getConnection();//調用獲取數據庫鏈接的方法 String sql="select * from account where a_name=?";//sql語句 User user = new User(); try { PreparedStatement ps = conn.prepareStatement(sql);//通過ps預編譯SQL語句,防止SQL注入 ps.setString(1, username);//插入sql語句參數 ResultSet rs = ps.executeQuery(); //獲取數據庫查詢返回的數據 if(rs.next()) { //將查詢到的數據存入User對象,如果沒有返回一個空的對象,表示用戶不存在 user.setId(rs.getInt(1)); user.setName(rs.getString(3)); user.setPassword(rs.getString(4)); } ps.close(); conn.close(); //關閉連接 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return user; } }
接下來就是service層了,照樣我們這里用到了接口,這里我自定義了一個異常,如果用戶名不存在或者密碼錯誤就向上拋一個異常,servlet再捕獲異常,將異常信息打印到頁面,提示用戶。具體代碼
service代碼:
//接口 public interface UserService { public void login(User user)throws PipiException; } //實現接口 public class UserServiceImpl implements UserService { @Override public void login(User user) throws PipiException { // TODO Auto-generated method stub UserDao dao = new UserDaoImpl();//導入Dao層包 String username = user.getName(); User loginUser = new User(); loginUser = dao.findByName(username);//將Dao層返回的對象存入loginUser if(loginUser.getName()==null) { throw new PipiException("賬戶名不存在!"); //數據庫返回的信息為空,說明用戶名不存在 } if(!user.getPassword().equals(loginUser.getPassword())) { throw new PipiException("密碼錯誤!"); //用戶輸入的密碼和查詢出的用戶密碼不一致,拋出密碼錯誤異常 } } }
自定義異常:
public class PipiException extends Exception{ public PipiException(String msg) { super(msg); } }
servlet:這里用到了servlet3.0的注解,注解的好處方便了界面與servlet交互的過程,不再使用web.xml文件配置action,可以直接使用html傳值,省去了編寫jsp頁面。
獲取到傳來的方法后,我們通過反射將servlet里的方法一個一個的分出來了,更方便的去調用該使用的方法。
@WebServlet("/UserServlet")//servlet注解, public class UserServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String methodname = request.getParameter("method");//獲取頁面調用的方法 try { Class clazz = Class.forName("com.pi.servlet.UserServlet");//獲取到UserServlet類 Method[] methods = clazz.getDeclaredMethods();//然后把類的方法一塊一塊的分出來 for (Method method : methods) { String name = method.getName(); //遍歷類的方法,如果和傳入的方法名相同就調用此方法 if (name.equals(methodname)) { method.invoke(clazz.newInstance(), request, response); break; } } } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } protected void doLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("charset=utf-8"); PrintWriter out = response.getWriter(); //獲取writer方法,用於將數據返回給ajax UserService us = new UserServiceImpl();//調用service String logname = request.getParameter("logname");//獲取輸入的用戶名 String logpass = request.getParameter("logpass");//獲取輸入的密碼 User user = new User(); user.setName(logname); user.setPassword(logpass); try { us.login(user); request.getSession().setAttribute("username", user.getName());//登錄成功,將用戶名存入session out.print(true);//返回true,表示登錄成功 } catch (PipiException e) { // TODO Auto-generated catch block String msg = e.getMessage(); request.setAttribute("msg", msg);//返回登錄錯誤的信息 out.print(false);//返回false,表示登錄失敗 } out.flush(); out.close(); } }
html頁面,css樣式太多我這里就不貼代碼了:
<head> <meta charset="UTF-8"> <title>登錄</title> <link rel="icon" type="image/x-icon" href="././images/bitbug_favicon.ico"> <link rel="stylesheet" type="text/css" href="index.css"> <script type="application/javascript" src="js/jquery.min.js"></script> </head> <body> <div class="container demo-1"> <div class="content"> <div class="large-header"> <div class="logo_box"> <h3>XXX管理系統</h3> <form action="#" name="f" method="post"> <div class="input_outer"> <span class="u_user"></span> <li id="c_user" class="c_user"></li> <input id="loginname" name="logname" class="text" style="color: #FFFFFF !important" type="text" placeholder="請輸入賬戶"> </div> <div class="input_outer"> <span class="us_uer"></span> <input id="loginpass" name="logpass" class="text" style="color: #FFFFFF !important; position:absolute; z-index:100;"value="" type="password" placeholder="請輸入密碼"> </div> <div class="mb2"> <input id="logbot" type="button" class="act-but submit" style="color: #FFFFFF" value="登錄"> </div> </form> </div> </div> </div> </div> </body> </html>
$.ajax部分:
這里我們在用戶輸入完用戶名后,就通過ajax去查詢用戶名是否存在,沒有就顯示一個×,存在就顯示綠色的勾。用戶點擊登錄后就再通過ajax去查詢密碼是否匹配,成功則跳轉到相應頁面,具體代碼:
$('#loginname').focus(function(){$('#c_user').css({"background":"none"});}); $('#loginname').blur(function(){//獲取用戶名框失去焦點事件,輸入完就查詢用戶名是否存在 if ($("[name='logname']").val() == "") { $("[name='logname']").focus();//如果用戶不輸入用戶名,就一直停留在這里 return; } $.ajax({ url:"UserServlet?method=findAccount",//傳入的servlet和對應的方法 type:"post",//提交方式 dataType:"json",//提交的數據為json串 data:{"logname":$('#loginname').val()},//傳入的數據為輸入的登錄名 beforeSend:function(){ $('#c_user').css({"background":"url(images/load.png)","background-size":"25px","animation-name":"go","animation-duration":"2s","animation-iteration-count":"infinite"}); },//在沒有得到servlet響應之前,加載的小圖標一直轉呀轉 success:function(data){//得到servlet傳回的數據后,進行處理 if(data==false){//false表示用戶不存在 $('#c_user').css({"background":"url(images/error.png)","background-size":"25px","animation-name":"none"}); }else{//表示用戶名存在 $('#c_user').css({"background":"url(images/noerror.png)","background-size":"25px","animation-name":"none"}); } }, }); }); $('#logbot').click(function(){//點擊登錄按鈕事件,執行登錄驗證 if ($("[name='logname']").val() == "") { $("[name='logname']").focus(); return; } if ($("[name='logpass']").val() == "") { $("[name='logpass']").focus(); return; } $.ajax({ url:"UserServlet?method=doLogin", type:"post", dataType:"json", data:{"logname":$('#loginname').val(),"logpass":$('#loginpass').val()},//數據為登錄名和登錄密碼 beforeSend:function(){ $('#logbot').val("登錄中"); }, success:function(data){//處理返回的信息,true則跳轉,false則提示密碼錯誤 if(data==false){ $("[name='logpass']").val(""); $("[name='logpass']").attr('placeholder',"密碼錯誤"); $('#logbot').val("登錄"); }else{ window.location.href = 'html/defaul/defaul.jsp'; } }, }); });
這次的demo分析就完了,簡單實用的登錄驗證就實現了,貼一下大致的界面圖
最后歡迎大家來到知了堂社區一起學習成長——傳送門:http://www.zhiliaotang.com