一.实现登录验证的步骤

  这次的小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 {/*** 通过账户名查询账户*/@Overridepublic User findByName(String username) {// TODO Auto-generated method stubConnection 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 {@Overridepublic void login(User user) throws PipiException {// TODO Auto-generated method stubUserDao dao = new UserDaoImpl();//导入Dao层包String username = user.getName();User loginUser = new User();loginUser = dao.findByName(username);//将Dao层返回的对象存入loginUserif(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方法,用于将数据返回给ajaxUserService us = new UserServiceImpl();//调用serviceString 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());//登录成功,将用户名存入sessionout.print(true);//返回true,表示登录成功} catch (PipiException e) {// TODO Auto-generated catch blockString 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

转载于:https://www.cnblogs.com/paopaolong/p/7441550.html

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

  1. 【知了堂学习笔记】java 自定义异常

    [知了堂学习笔记]java 自定义异常 参考文章: (1)[知了堂学习笔记]java 自定义异常 (2)https://www.cnblogs.com/pipixiao/p/7419902.html ...

  2. [知了堂学习笔记]根据银行卡号匹配银行卡类型

    银行卡类型匹配代码 原理:通过银行卡前6或前8位对银行卡类型进行匹配,返回对应的银行类型 代码: package com.finalcial.util;/*** 通过银行的Bin号 来获取 银行名称 ...

  3. [知了堂学习笔记]_Java中线程的学习(一)

    请关注"知了堂学习社区",地址:http://www.zhiliaotang.com/portal.php 线程 1.线程的概念 线程,有时被称为轻量级进程(Lightweight ...

  4. [知了堂学习笔记]_设计模式之工厂模式

    介绍: 工厂模式专门负责将大量有共同接口的类实例化.工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类. 形态: 简单工厂(Simple Factory)模式,又称静态工厂方法模式 ...

  5. 【知了堂学习笔记】_Java笔试题整理(二)

    请关注"知了堂学习社区",地址:http://www.zhiliaotang.com/portal.php 1.请大概描述一下Vector和ArrayList的区别,Hashtab ...

  6. 【知了堂学习笔记】_JavaScript之DOM操作(英语在线翻译)

    请关注"知了堂学习社区",地址:http://www.zhiliaotang.com/portal.php 此案例样式粗糙,主要注重功能实现!! <!DOCTYPE html ...

  7. JavaWeb 实验 Servlet用户登录验证

    实验2.2 Servlet用户登录验证 实验内容: 编写JSP程序,实现用户提交登录表单给Servlet,由Servlet 查询数据库(模拟查询,不用真的连接数据库查询),对用户是否存在进行验证. 实 ...

  8. 知了堂学习笔记-CSS样式整理(一)

    height.width 在height.width属性中使用%值,需要对包含它的块级对象设置宽高,否则height.width属性设置无效.因为%是基于包含它的块级对象的百分比高度. 无效: 有效: ...

  9. 【知了堂学习笔记】MySQL数据库常用的SQL语句整理

    一,常用.简单的SQL操作语句 1.数据库操作: 1)创建数据库: create database database_name: 创建并设置字符编码 create database database_ ...

  10. [知了堂学习笔记]_网络基础知识_1.OSI参考模型(网络七层协议)

    OSI参考模型是国际标准化组织ISO制定的模型,把计算机与计算机之间的通信分成七个互相连接的协议层,如图: 1.1各层功能 1.物理层 最底层是物理层,这一次负责传送比特流,它从第二层数据接收数据帧, ...

最新文章

  1. Servlet学习DAY_01:服务器概念/Web服务器的作用/ Servlet概念/ 如何关联和解除Tomcat/ 创建一个Web工程 /Servlet响应流程/ Get-Post /常见异常
  2. React ES6组件里绑定this的三种方式
  3. jtag引脚定义_硬件学习之通过树莓派操控 jtag
  4. false sharing
  5. Android新增Activity,并实现多Activity之间的切换
  6. php源码编程,10个小技巧让你做好php源码编程
  7. 计算机博士两篇一区两篇会议,本科博士联手!西电陈渤团队两篇论文被顶级会议录用...
  8. 《Cortex-M0权威指南》之体系结构---栈空间操作
  9. TCL——事务控制语言
  10. 【转】The C10K problem(翻译 中文版)
  11. 【人脸识别】基于matlab GUI Gabor+SVM比较PCA+SVM人脸识别【含Matlab源码 685期】
  12. Java第一周总结1016
  13. 利用JDBC连接服务器数据库(Android)
  14. linux中设置ssh登录时显示的banner
  15. Quantopian投资组合和绩效分析工具:Pyfolio
  16. myeclipse 6.5注册码
  17. 关于“#define REG_MEM_BASE (*(volatile unsigend long *)(PA_BAES + 0x00000050))”语句的解析
  18. 机器学习:特征提取与特征选择意义及目的
  19. Vs2005下重复定义的问题解决 ... already defined in ...
  20. 零基础学ps入门视频全套教程,ps教程入门视频分享给大伙!

热门文章

  1. git指定版本openwrt源码_关于Github Action自动编译Lean_Openwrt的配置修改问题
  2. java文件的打包和解包,Java包装类:什么是包装类对象,什么是打包和解包,当编译遇到自动打包和解包时会发生什么?...
  3. 【牛客小白赛12:J/2019南昌网络赛:M/牛客练习赛23:D】查询字符串ss是否是字符串s的子序列(序列自动机裸题)
  4. 后缀树c语言算法,C语言数据结构之中缀树转后缀树的实例
  5. 漫话:如何给女朋友解释什么是反向代理、正向代理?
  6. 算法:Validate Binary Search Tree(验证二叉查找树)
  7. qt最大化和还原实现_Qt 窗口操作函数(置顶、全屏,最大化最小化按钮设置等)...
  8. 中山大学计算机学院官网万海,中山大学
  9. 2021-09-1364. 最小路径和
  10. Linux下mysql5.7.18登录报错“Access denied for user 'root'@'localhost' (using password: YES”)