第一步:

  1、为项目配置 Tomcat 为 server:

      

  2、导入 mysql的jar包 到项目目录中:

      

第二步:编码

1、数据库连接类ConnectMysql.java代码:

 package com.testing.mysql;

 import java.sql.Connection;
import java.sql.DriverManager; public class ConnectMysql {
//设置连接的成员变量
public Connection conn;
//数据库的远程连接地址、用户名和密码,此处是我自己的虚拟机里面的MySQL数据库(库名为test_project)和虚拟机的登录用户名、密码
public static final String DBURL="jdbc:mysql://192.168.112.128:3306/test_project?useUnicode=true&autoReconnect=true&characterEncoding=utf-8";
public static final String DBUSER="root";
public static final String DBPWD="";
//构造方法
public ConnectMysql() {    //此处也可以将地址、用户名、密码作为参数传入,后期调用时就可以参数化调用这个方法
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(DBURL, DBUSER, DBPWD);
//设置连接的超时时间
DriverManager.setLoginTimeout(10);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

2、创建UseMysql的类:

 package com.testing.mysql;

 import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map; public class UseMysql { // 数据库连接对象
private Connection ct; // 构造函数中初始化这个数据库连接对象
public UseMysql(Connection conn) {
ct = conn;
} /**
* @param name登录用户名
* @return 返回查询信息的结果集合
*/
public Map<String, String> getUserInfo(String name) {
String sql = "SELECT * FROM userinfo where username='" + name + "';";
System.out.println(sql);
// 保存查询结果的集合
ResultSet rs = null;
// 声明statement对象,通过这个对象查询数据库
Statement sm;
try {
// 通过数据库连接实例化statement对象
sm = ct.createStatement();
// 执行查询
rs = sm.executeQuery(sql); // 创建map存储表中信息
Map<String, String> map = new HashMap<String, String>(); // 设置读取结果的循环控制变量,代表获取的数据的行数
int j = 1; /*
* rs!=null说明sql语句执行查找成功,有内容返回。 rs.next()代表着集合当中还有下一个元素(一行的数据),并且读取该行的值。
* 如果sql查询不止一条语句(有用户名重名的情况),则可以用while循环取这些值
*/
while (rs != null && rs.next()) {
// 元组数据代表数据库查询结果中的一行,通过rsmd来获取数据的列数
ResultSetMetaData rsmd = rs.getMetaData();
// 注意sql中的列从1开始,遍历一行数据中的每列内容,并以键值对形式存储到map中去
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
// 展示的信息去除密码列和用户名列
if (!(rsmd.getColumnName(i).equals("pwd") || rsmd.getColumnName(i).equals("username")))
// 将每一列的名称和数据作为键值对存放到map当中,将行数拼接到键里
map.put(rsmd.getColumnName(i) + j, rs.getString(i));
}
System.out.println(map.toString()); // 行数自增
j++;
}
// 关闭statement对象和查询结果集合对象,释放资源
sm.close();
rs.close();
return map;
} catch (Exception e) {
// TODO: handle exception
}
return null;
} /**
* 通过查询语句验证登录结果的登录方法,如果能够查询到结果,则说明登录成功
*
* @param 登录用户名name
* @param 登录密码password
* @return 返回登录是否成功的布尔值,成功为true,失败为false
*/
public boolean Login(String name, String pwd) { String sql = "SELECT * FROM userinfo WHERE username='" + name + "' AND pwd='" + pwd + "';";

// 声明数据库连接状态statement对象,通过这个对象查询数据库
Statement sm;
// 设置一个变量来保存查询结果集
ResultSet rs = null; try {
// 通过数据库连接实例化一个statement对象sm
sm = ct.createStatement(); // 执行查询语句
rs = sm.executeQuery(sql); // rs!=null说明sql语句执行查找成功,有内容返回,
// 封装的方法rs.next()代表着集合当中还有下一个元素(一行的数据),并且读取该行的值。
if (rs != null && rs.next()) { // 元组数据代表数据库查询结果中的一行。
ResultSetMetaData rsmd = rs.getMetaData(); // 声明一个map来存储一条记录中的内容
HashMap<String, String> map = new HashMap<String, String>(); // 注意sql中的列从1开始,遍历一条记录中的每列内容,并以键值对形式存储到map中去
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
// 从第一列开始遍历一条记录中的每一列,将对应的键值对存储到map当中
map.put(rsmd.getColumnName(i), rs.getString(i));
}
System.out.println(map.toString());
// 关闭statement对象和查询结果集合对象,释放资源
sm.close();
rs.close();
// 如果查询结果不为空,就返回登录成功
return true;
}
// 如果查询结果为空,也要关闭对象释放资源
sm.close();
rs.close();
} catch (SQLException e) {
}
// try建立查询失败或者查询结果为空都会执行到这里,返回false
return false;
} /**
* 通过 存储过程 验证登录结果的登录方法,如果能够查询到结果,则说明登录成功 使用存储过程进行验证时,sql语句不再重新编译,可以防止sql注入
*
* @param 登录用户名name
* @param 登录密码password
* @return 返回登录是否成功的布尔值,成功为true,失败为false
*/
public boolean PLogin(String name, String pwd) {
try {
// 创建调用存储过程的对象,参数用?号代替,不要直接传递参数
CallableStatement cm = ct.prepareCall("{call login(?,?)}");
// 通过set方法传递存储过程用到的参数,1和2代表第几个参数,name和pwd代表参数值
cm.setString(1, name);
// cm.setInt(1, 1);
cm.setString(2, pwd);
// 获取查询结果
ResultSet rs = cm.executeQuery();
// 处理查询结果,与之前的方法一致,不再重复添加注释了
if (rs != null && rs.next()) {
ResultSetMetaData rsmd = rs.getMetaData();
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
map.put(rsmd.getColumnName(i), rs.getString(i));
}
System.out.println(map.toString());
cm.close();
rs.close();
return true;
}
cm.close();
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
return false;
} }

3、登录的后台  LoginTry.java 代码:

 package com.testing.login;

 import java.io.IOException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.testing.mysql.ConnectMysql;
import com.testing.mysql.UseMysql; /**
* Servlet implementation class LoginTry
*/
@WebServlet("/LoginTry")
public class LoginTry extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public LoginTry() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { ........ /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub // 返回值编码的修改
response.setContentType("text/html;charset=UTF-8");
// 收到的参数的编码修改
request.setCharacterEncoding("UTF-8"); String user = request.getParameter("userid");    //“userid”要与前端form表单中的用户名的<input>元素的name属性对应
String pwd = request.getParameter("pwds");      //“pwds”要与前端form表单中的密码的<input>元素的name属性对应 //声明一个数据库查询结果实例
Map<String, String> userinfo; //设置正则匹配模式,进行用户名和密码的正则过滤
String regEx = "[^a-zA-Z0-9_-]";
Pattern p = Pattern.compile(regEx);
// 调用pattern对象p的mathcer方法,生成一个匹配matcher对象
Matcher m = p.matcher(user);
Matcher m1 = p.matcher(pwd);
//设置返回信息的变量res
String res = "{"; // 判断用户名密码不为空
if (user != null && pwd != null) {
// 判断长度3~16位
if (user.length() > 2 && user.length() < 17 && pwd.length() > 2 && pwd.length() < 17) {
// 判断不包含特殊字符
if (!m.find() && !m1.find()) { // 创建sql连接,以及实例化UseMysql类型
ConnectMysql connSql = new ConnectMysql();
UseMysql mySql = new UseMysql(connSql.conn);
//使用创建的对象来调用UseMysql类中的Login(user,pwd)方法并将返回的布尔结果作为判断值
if (mySql.Login(user, pwd)) {
res += "\"status\":200,\"msg\":\"恭喜您,登录成功!\"}";
userinfo = mySql.getUserInfo(user);
} else {
res += "\"status\":3000,\"msg\":\"用户名密码不匹配!\"}";
} } else {
res += "\"status\":3003,\"msg\":\"用户名密码不能包含特殊字符!\"}";
}
} else {
res += "\"status\":3004,\"msg\":\"用户名密码长度必须是3至16位!\"}";
}
} else {
res += "\"status\":3005,\"msg\":\"用户名密码长度不能为空!\"}";
}
// 接口返回信息,返回信息中显示本次请求时的sessionID
response.getWriter().append(res); } }

4、前端界面 index.html 代码:

 <!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html" charset="utf-8">
<title>zzp的网页</title> <!--接下来引入JQuery最小版本的库文件 -->
<script src="jquery.min.js" type="text/javascript"></script>
<!-- 接下来引入自己写的js库文件 -->
<script src="test.js" type="text/javascript"></script> </head> <body >
<h1 align="center">Hello HTML</h1> <form id="loginForm" method="post" action="./LoginTry">
<div id="info" style="text-align:center">
<p>请输入您的账号:</p>
<input type="text" name="userid" placeholder="登录名" />
<br/>
<p>请输入您的密码:</p>
<input type="password" name="pwds" placeholder="密码" />
<br/><br/> <!-- 下面这一句原本是为了使用form表单的方式来调用post方法的 -->
<!-- <input type="submit" value="开始登录"> --> <!-- 使用“登录”按钮的onclick事件来调用js文件,执行post方法的异步请求 -->
<input type="button" onclick="javascript:loginJS()" value="登录" />
</div>
</form> </body>
</html>

5、用到的js代码:

 /**
* 点击登录界面中“登录”按钮会调用的js方法
*/ function loginJS() { // 定义一个存放URL的变量,指定请求的接口地址
var AjaxURL = "http://localhost:8080/LoginInterServlet/LoginTry"; $.ajax({
url : AjaxURL,
type : "post", // 采用post方法
dataType : "json", // 请求和返回的参数格式;如果是非json格式需要使用text格式
// 获取id=loginForm的form表单中的参数
data : $('#loginForm').serialize(), // 当接口调用成功时,执行success中的方法,result参数指的是接口返回的信息
success : function(result) {
// result[***]表示的是对应的键经过 解析后的值
// alert("status:"+result["status"]+", "+result["msg"]); //如果登录成功,将id=“info”的元素改为接口返回值中“msg”信息
$('#info')[0].innerText=result["msg"];
}, // 当接口调用失败时,执行error中的方法
error : function() {
alert("服务器忙……请稍后重试!");
}
}); }

运行验证:

  

结果截图:

eclipse的控制台运行后的结果截图:

数据库中数据截图:

java编程(2)——servlet和Ajax异步请求的接口编程(有调用数据库的数据)的更多相关文章

  1. java编程(1)——servlet和Ajax异步请求的接口编程(没有调用数据库的数据)

    编程应用背景: 使用HttpServlet接口来编写一个动态登录的接口(需要在Tomcat容器发布) 登录的 LoginSample 类代码: package com.zhang.java; publ ...

  2. ajax异步请求

    做前端开发的朋友对于ajax异步更新一定印象深刻,作为刚入坑的小白,今天就和大家一起聊聊关于ajax异步请求的那点事.既然是ajax就少不了jQuery的知识,推荐大家访问www.w3school.c ...

  3. 关于我们ajax异步请求的方法与知识

      做前端开发的朋友对于ajax异步更新一定印象深刻,作为刚入坑的小白,今天就和大家一起聊聊关于ajax异步请求的那点事.既然是ajax就少不了jQuery的知识,推荐大家访问www.w3school ...

  4. maven工程 java 实现文件上传 SSM ajax异步请求上传

    java ssm框架实现文件上传 实现:单文件上传.多文件上传(单选和多选),并且用 ajax 异步刷新,在当前界面显示上传的文件 首先springmvc的配置文件要配置上传文件解析器: <!- ...

  5. java判断请求是否ajax异步请求

    java判断请求是否ajax异步请求   解决方法: if (request.getHeader("x-requested-with") != null && re ...

  6. 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回

    作者:ssslinppp      时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MV ...

  7. Ajax -异步请求 -jquery中ajax分类 -第一层 $.ajax -第二层($.get /$.post) -第三层($.getJson/$.getScript) -相应演示

    Ajax 1.标准请求响应时浏览器的动作(同步操作) 1.1浏览器请求什么资源,跟随显示什么资源2.ajax:异步请求. 2.1局部刷新,通过异步请求,请求到服务器资源数据后,通过脚本修改页面中部分内 ...

  8. art.dialog 与 ajax 异步请求

    上周写了一些代码,涉及到jquery异步请求,这里归纳总结下,希望对刚接触编程的同学有帮助. 主要习惯使用 art.dialog 框架,非常好用,在异步请求上,它提供了很多简便的方法. 加载使用art ...

  9. ajax异步请求302分析

    1.前言 遇到这样一种情况,打开网页两个窗口a,b(都是已经登录授权的),在a页面中退出登录,然后在b页面执行增删改查,这个时候因为授权原因,b页面后端的请求肯定出现异常(对这个异常的处理,进行内部跳 ...

随机推荐

  1. JAVA 中的命名规则

    命名规则– 基本要求• 见名知意– 常见命名的规则 • 包 (其实就是文件夹,用于对类进行管理)– 全部小写, 多级包用点隔开.– com,com.itheima • 类– 一个单词首字母大写 Stu ...

  2. Windows系统封装教程

    Windows系统封装教程

  3. python验证卡普耶卡(D.R.Kaprekar)6174猜想

    1955年,卡普耶卡(D.R.Kaprekar)对4位数字进行了研究,发现一个规律: 对任意各位数字不相同的4位数,使用各位数字能组成的最大数减去能组成的最小数,对得到的差重复这个操作,最终会得到61 ...

  4. 2018-2019-2 《Java程序设计》第9周学习总结

    20175319 2018-2019-2 <Java程序设计>第9周学习总结 教材学习内容总结 本周学习任务: 下载安装MySQL数据库管理系统. 教材介绍在官网下载安装Mysql服务,启 ...

  5. 深入浅出mybatis之缓存机制

    目录 前言 准备工作 MyBatis默认缓存设置 缓存实现原理分析 参数localCacheScope控制的缓存策略 参数cacheEnabled控制的缓存策略 总结 前言 提到缓存,我们都会不约而同 ...

  6. O2O淘宝优惠券代码总结

    一.数据集预处理 1.数据读入 import pandas as pd import numpy as np import datetime as date import datetime as dt ...

  7. 使用JQuery实现图片轮播效果

    [效果如图] [原理简述] 这里大概说一下整个流程: 1,将除了第一张以外的图片全部隐藏, 2,获取第一张图片的alt信息显示在信息栏,并添加点击事件 3,为4个按钮添加点击侦听,点击相应的按钮,用f ...

  8. luogu P5319 [BJOI2019]奥术神杖

    传送门 要求的东西带个根号,这玩意叫几何平均数,说到平均数,我们就能想到算术平均数(就是一般意义下的平均数),而这个东西是一堆数之积开根号,所以如果每个数取对数,那么乘法会变成加法,开根号变成除法,所 ...

  9. 最近面试被问到一个问题,AtomicInteger如何保证线程安全?

    最近面试被问到一个问题,AtomicInteger如何保证线程安全?我查阅了资料 发现还可以引申到 乐观锁/悲观锁的概念,觉得值得一记. 众所周知,JDK提供了AtomicInteger保证对数字的操 ...

  10. mac charles手机抓包详细教程

    1.官方下载charles 2.查看电脑IP地址 3.Proxy>Proxy Settings>勾选 Enable transparent HTTP proxying  (记住端口号 88 ...