一.实现登录验证的步骤
这次的小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