• 【知了堂学习笔记】$.ajax配合Servlet实现登录验证


    一.实现登录验证的步骤

      这次的小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

  • 相关阅读:
    window.setInterval
    用gcc/g++编译winsock程序
    Yii 三表关联 角色表、角色权限连接表、权限表
    访问CGI程序时不添加 /cgi-bin/ 目录也可访问
    Linux 目录递归赋权,解决 Linux权限不够
    Linux 下用C语言连接 sqlite
    ORACLE中添加删除主键
    Linux 杀死进程
    Oracle 查询重复数据
    exlipse php 插件安装地址
  • 原文地址:https://www.cnblogs.com/paopaolong/p/7441550.html
Copyright © 2020-2023  润新知