1.定义
Ajax即Asynchronous Javascript And XML,(底层是xml)
使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上
基于AJAX实现异步刷新技术
基于AJAX实现局部刷新技术
局部刷新:
每针对一个表单,进行验证,而不是所有的一起验证,如submit和action.
异步刷新:
一个页面切分成多个模块,每个模块玩我自己的。
比如有好多表单,
这些表单同时求证(一次性请求)》 同步请求
每个请求校验它自己的,类似于多线程(多进程)同时请求 》 异步请求
有ajax就不用submit和action
2.为什么使用Ajax(性能优化)==》面试题上下
不重新加载整个网页的情况下,对网页的某部分进行更新,提高性能。
3.语法
$.ajax使用方法
常用参数:
1、url 请求地址 ==》去调后端
2、type 请求方式 ,默认是’get’,常用的还有’post’ =》以什么请求方式去调请求
3、dataType 设置返回的数据格式,常用的是’json’格式,也可以设置为’text’
后端返回给数据到前端,它所匹配的数据类型
4、data 设置客户端(即前端)发送给服务器(后端)的数据 (类似于数组)
(格式协议的设置或规则的匹配)客户端需要匹配的类型
5、success 设置请求成功后的回调函数(前端发送请求到后端)
6、error 设置请求失败后的回调函数
7、async 设置是否异步,默认值是’true’,表示异步
定义方法,定义一堆Ajax, 后面有一堆的值
如果希望执行Ajax后继续执行值,设置async:false
true会异步,Ajax之后的脚本会同时执行,
会导致先执行值(return),再执行Ajax,有一堆问题。
“url”:“UserServlet?action=validate”, “data”:{“name”:name,“pwd”:pwd},
等价于 UserServlet?action=validate&name==xxx&pwd=xxx
4.实战
(1)创建工程,数据库
导入jar包(javax.servlet\jstl\standard\servlet-api\mysql),js包,
(2)cn.kgc.util/BaseDao
import java.sql.*;
public class BaseDao {
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
private static final String USER = "root";
private static final String PWD = "zjj";
protected Connection conn = null;
protected PreparedStatement pstmt = null;
protected ResultSet rs = null;
//加载驱动
static {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 获取连接
public void getConnection() {
try {
conn = DriverManager.getConnection(URL, USER, PWD);
System.out.println(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
//关闭资源的方法
public void closeAll() {
try {
if (rs != null) rs.close();
} catch (SQLException e) {e.printStackTrace();}
try {
if (pstmt != null) pstmt.close();
} catch (SQLException e) {e.printStackTrace();}
try {
if (conn != null) conn.close();
} catch (SQLException e) {e.printStackTrace();}
}
//增删改的通用方法
public int executeUpdate(String sql, Object[] params) {
int num = 0;
getConnection();
try {
pstmt = conn.prepareStatement(sql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
num = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally { closeAll(); }
return num;
}
//查询的通用方法
public ResultSet executeQuery(String sql, Object[] params) {
getConnection();
try {
pstmt = conn.prepareStatement(sql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
rs = pstmt.executeQuery();
} catch (SQLException e) { e.printStackTrace(); }
return rs;
}
public static void main(String[] args) {
BaseDao baseDao = new BaseDao();
baseDao.getConnection();
}
}
(3)cn.kgc.entity/User
省略
(4)cn.kgc.dao/UserDao、UserDaoImpl
UserDao
import cn.kgc.entity.User;
public interface UserDao {
//1.定义校验用户名是否存在的方法
User findByName(String name);
//2.定义校验用户名和密码是否同时正确的方法
User findByNameAndPwd(User user);
}
UserDaoImpl
package cn.kgc.dao;
import cn.kgc.entity.User;
import cn.kgc.util.BaseDao;
import java.sql.SQLException;
public class UserDaoImpl extends BaseDao implements UserDao {
@Override
public User findByName(String name) {
User user = null;
rs = super.executeQuery("select * from t_user where name = ?",new Object[]{name});
try {
while (rs.next()){
user = new User(rs.getInt("id"),rs.getString("name"),rs.getString("pwd"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {super.closeAll();}
return user;
}
@Override
public User findByNameAndPwd(User user) {
User uu = null;
rs = super.executeQuery("select * from t_user where name = ? and pwd = ?",
new Object[]{user.getName(),user.getPwd()});
try {
while (rs.next()){
uu = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setPwd(rs.getString("pwd"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {super.closeAll();}
return uu;
}
}
(5)cn.kgc.service/UserService、UserServiceImpl
UserService
import cn.kgc.entity.User;
public interface UserService {
//定义validate校验方法
String validate(User user);
}
UserServiceImpl
package cn.kgc.service;
import cn.kgc.dao.UserDao;
import cn.kgc.dao.UserDaoImpl;
import cn.kgc.entity.User;
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
@Override
public String validate(User user) {
//1 . message的作用就是通过ajax传递message参数给jsp页面 标识符
String message = "";//null?
// a=""已经在内存存了东西 a = null表示内存空间上没有存东西
// 例子:a="" 就相当于这个人考试了,不过是考了0分;
// 而 a=null 就相当于这个人没有考试,所以没有分数,但你不能说他是0分。
//判断前端是否传递的用户名是否没有传,或者传递的是空的字符串 比如空格
if (user.getName()!=null && !"".equals(user.getName())){//判空 和 嵌套
// " "和里面的字符串代表的是一个String对象,equals是方法,将字符串与指定的对象比较
// "".equals()的括号中内容如果也是空字符串,那么就返回true
//2.从前端获取用户名,校验登录用户名是否存在
User u = userDao.findByName(user.getName());
if (u==null){
//3.基于用户名不存在的情况下,如果说数据库里面通过名称(查询数据库)未获取到用户名变量,则message 设置为"100”(返回值标识码“100”)
message = "100";//传递给Ajax
}else{
//4.则否数据库里面通过名称(查询数据库)可以获取到用户名变量。
//5.基于用户名存在的情况下,则可以继续判断数据库中的用户名和密码是否正确
User u2 = userDao.findByNameAndPwd(new User(user.getName(),user.getPwd()));
if (u2 == null){
//6.如果用户名或者密码不正确,则u2为null,则给message赋值“200” (返回值标识码“200”)
message = "200";
}
}
}
return message;
}
}
(6)cn.kgc.servlet/UserServlet
package cn.kgc.servlet;
import cn.kgc.entity.User;
import cn.kgc.service.UserService;
import cn.kgc.service.UserServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class UserServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
String action = request.getParameter("action");
if (action.equals("toLogin")){
request.getRequestDispatcher("login.jsp").forward(request,response);
}else if (action.equals("validate")){
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
User user = new User(name,pwd);
UserService userService = new UserServiceImpl();
String validate = userService.validate(user);
response.getWriter().print(validate); // ==》 响应给客户端的东西
// 加ln 不能解析 /r/n
// response.getWriter()返回的是PrintWriter,这是一个打印输出流
//print
//response.getWriter().print(),不仅可以打印输出文本格式的(包括html标签),
//还可以将一个对象以默认的编码方式转换为二进制字节输出
//writer
//response.getWriter().writer(),只能打印输出文本格式的(包括html标签),不可以打印对象
//write():仅支持输出字符类型数据,字符、字符数组、字符串等
//print():可以将各种类型(包括Object)的数据通过默认编码转换成bytes字节形式,
//这些字节都通过write(int c)方法被输出
}
}
}
(7)web.xml
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>cn.servlet.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/UserServlet</url-pattern>
</servlet-mapping>
(8)login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
//jquery初始化函数
$(function () {
//1.触发loginBtn按钮
$("#loginBtn").bind("click",function () {
// bind()方法为被选元素添加一个或多个事件处理程序,
//并规定事件发生时运行的函数。
// 2.没有获取焦点导致没有失去焦点,加个判空校验即可
var name = $("[name=name]").val();
if (name==""){
alert("用户名不能为空");
return false;
}
var pwd = $("[name=pwd]").val();
if (pwd==""){
alert("用户密码不能为空");
return false;
}
//3.调用第一个校验 标识位
var flag = validate1();
if (flag){
//4.如果第一个校验成功,调用第二个校验
var flag2 = validate2();
if (flag2){
//5.如果第二个校验也成功,则跳转到主页面
window.location.href = "index.jsp";
}
}
});
});
// 使用迭代测试,一步一步来
// 定义 validate()校验方法
function validate1() {
var flag = true;
$.ajax({ //UT2D 顺序无所谓
"url": "http://localhost:8080/UserServlet?action=validate",
//可加双引号 可不加
//前后端分离必须要加 前面的地址
"type": "post",
async: false,
"data": {"name":$("[name = name]").val(),"pwd":$("[name = pwd]").val()},
//json带 花括号
//"data":{"name":name,"pwd":pwd},
"dataType": "text",
"success": function (data){//等价于validate
// alert("data" + data);
$("#message1").empty();//清空message1
$("#message2").empty();
if (data == "100"){
$("#message1").text("用户名不存在");
flag = false;
return false;
}
},
"error": function (){}
});
return flag;
}
function validate2() {
var flag = true;
$.ajax({
"url": "http://localhost:8080/UserServlet?action=validate",
"type": "post",
async: false,
"data": {"name":$("[name = name]").val(),"pwd":$("[name = pwd]").val()},
"dataType": "text",
"success": function (data){
$("#message1").empty();
$("#message2").empty();
if(data=="200"){
$("#message2").text("用户名或密码错误");
flag = false;
return false;
}
},
"error": function (){}
});
return flag;
}
</script>
</head>
<body>
<form>
<table>
<tr>
<td>用户名</td>
<td>
<input type="text" name="name" onblur="validate1()">
<%-- onblur 属性在元素失去焦点时触发。onblur 常用于表单验证代码(例如用户离开表单字段)。--%>
<span style="color: red;" id="message1" ></span>
</td>
<%-- 失焦--%>
</tr>
<tr>
<td>密码</td>
<td>
<input type="text" name="pwd" onblur="validate2()">
<span style="color: red;" id="message2" ></span>
</td>
</tr>
<tr>
<td><input type="button" id="loginBtn" value="登录"></td>
</tr>
</table>
</form>
</body>
</html>
JQuery中的text(),html()和val()区别:
.html()用为读取和修改元素的HTML标签
.text()用来读取或修改元素的纯文本内容
.val()用来读取或修改表单元素的value值。
(9)index.jsp
<body>
登录成功!
</body>
结果:
http://localhost:8080/UserServlet?action=toLogin
当用户名输错,为下图:当用户名存在,用户名或密码不匹配,为下图:
成功,即如下图:http://localhost:8080/index.jsp
登录成功!
----2021.11.04&11.05