简单介绍:
在上一章节我们展示了关于jQuery的一些基本操作,接下来我们就要进行Ajax的一些基础操作,在真正执行操作之前,我们还需要一点前置的准备,就是关于发送和请求JSON数据的准备。
请求JSON数据:
JSON文件的数据是由一组方括号包裹多个花括号,花括号里面有多个键值对组成的。JSON的好处就是可以被处理成对象,方便我们获取其中的数据,不用复杂的截取数据操作。在我们的操作中,是将一个对象数据封装成为一个JSON格式的文件。
jar包准备(使用Maven帮我们下载):
在我们之前的下载中,是去官网找依赖包也就是jar包进行下载,但是我们这次需要下载的jar包有点多,有6个,所以我们使用maven来帮我们下载完之后在maven的本地仓库中直接复制过来就好了。
pom.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Maven_JavaWeb</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<classifier>jdk15</classifier>
<version>2.4</version>
</dependency>
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.ow2.util.bundles</groupId>
<artifactId>commons-collections-3.2.1</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
</project>
写好依赖项之后,一开始当然是红色的,因为它还没有扫描配置项并下载,剩下的就是我们需要刷新maven,等待一会他就会帮我们下载并配置好依赖项,里面的内容都变成正常的白色了,就表示已经下载完成了。当然我们这里并不需要它帮我们配置,我们只需要它帮我们下载就好了。下载好之后,如果你们之前使用过Maven并修改了本地仓库的路径,那就去你修改之后的本地仓库路径去寻找,如果你没有修改,那么默认的本地路径就在你的C:\Users\33680\.m2\repository下面就是本地仓库所有的依赖项。
具体的我们需要的jar包有六个:
找到这六个jar包之后,复制到lib文件夹下面就可以正常的使用了。
代码实现:
之前说过,我们是将Java类中的数据封装成一个JSON数据所以首先我们要有一个存放数据的JavaBean然后是发送端Servlet类去设置数据并发送数据,网页请求端JSP去请求数据以及将数据添加到网页中。
JavaBean类:
public class Book {
private String name;
private double price;
private String author;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Book(String name, double price, String author) {
this.name = name;
this.price = price;
this.author = author;
}
public Book() {
}
}
Servleyt类:
import net.sf.json.JSONArray;
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 java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@WebServlet(name = "ResponseJsonServlet" , value = "/ResponseJsonServlet")
public class ResponseJsonServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Book> lb = new ArrayList<>();
Book b1 = new Book();
b1.setName("《JavaWeb程序开发》");
b1.setAuthor("黑马程序员");
b1.setPrice(12);
Book b2 = new Book();
b2.setName("《Vue程序开发》");
b2.setAuthor("人邮教育");
b2.setPrice(12);
lb.add(b1);
lb.add(b2);
JSONArray jsonArray = JSONArray.fromObject(lb);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println(jsonArray);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
JSP页面:
<%--
Created by IntelliJ IDEA.
User: 33680
Date: 2022/11/29
Time: 15:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>请求Json数据</title>
<script src="jquery-3.6.1.js"></script>
</head>
<body>
<button type="button">请求数据</button>
<table class="dataTable">
<tr>
<td>作者</td>
<td>书名</td>
<td>价格</td>
</tr>
</table>
<script>
$('button').click(()=>{
$.getJSON('http://localhost:8080/ResponseJsonServlet',(data)=>{
let html ='';
for(var Book in data){
html += '<tr>'
for(var key in data[Book]){
html += '<td>' + data[Book][key] + '</td>'
console.log(data[Book][key])
}
console.log(data[Book])
html += '</tr>'
}
$('.dataTable').append(html);
})
})
</script>
</body>
</html>
运行效果:
我们可以直接访问一下这个Servle来看一下返回的数据的形式
然后再运行JSP文件实现效果:
Ajax请求:Ajax请求方式的特点主要表现在他是异步的,也就是不需要刷新网页就可以实现数据的请求。
请求方式:
和之前我们进行的请求一样,我们只需要使用$.ajax()的方式进行调用就可以,但是不同的是,ajax请求支持很多的参数来精确的调整我们的请求以及请求之后的各种动作。
参数列表:
该方法只有一个参数,但是这个对象里包含了$.ajax()方法所需要的请求设置以及回调函数等信息,参数以key/value的形式存在,所有的参数都是可选的。常用参数见下表:
1.url
要求为String类型的参数,(默认为当前地址)发送请求的页面。
2.type
要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。
3.timeout
要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。
4.async
要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。
5.cache
要求为Boolean类型的参数,默认为true(当dataType为Script时,默认为false),设置false将不会从浏览器缓存中加载请求信息。
6.data
要求为Object或String类型的参数,发送到服务器的数据。如果不是字符串,将自动转换为字符串格式。get请求中将附加在URL后。防止这种自动转换,可以查看 processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。
7.dataType
要求为String类型的参数,预期服务器返回的数据类型。如果不指定,jQuery将自动根据HTTP包的mine信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
xml:返回XML文档,可用jQuery处理。
html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
script:返回纯文本javascript代码。不会自动缓存结果,除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
json:返回JSON数据。
jsonp:JSON格式。使用JSONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
text:返回纯文本字符串。
8.beforeSend
要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是唯一的参数。
function(XMLHttpRequest){
this;//调用本次ajax请求时传递的options参数
}
9.complete
要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。
function(XMLHttpRequest,textStatus){
this; //调用本次ajax请求时传递的options参数
}
10.success
要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。
(2)描述状态的字符串。
function(data,textStatus){
//data可能是xmlDoc、jsonObj、html、text等
this; //调用本次ajax请求时传递的options参数
}
11.error
要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:
function(XMLHttpRequest,textStatus,errorThrown){
//通常情况下textStatus和errorThrown只有其中一个包含信息
this; //调用本次ajax请求时传递的options参数
}
12.contentType
要求为String类型的参数,当发送信息至服务器时。内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。
13.dataFilter
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataTYpe参数。函数返回的值将由jQuery进一步处理。
function(data,type){
//返回处理后的数据
return data;
}
14.global
要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart和ajaxStop可用于控制各种ajax事件。
15.ifModified
要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。
16.jsonp
要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。
17.username
要求为String类型的参数,用于响应HTTP访问认证请求的用户。
18.password
要求为String类型的参数,用于响应HTTP访问认证请求的密码。
19.processData
要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲而非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。
20.scriptCharset
要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。
这些参数全都都是放在一个对象里面以key-value的形式作为参数进行传递的,我们在一般的请求中不会全部使用只会使用几个比较常用的参数
代码实现:
发送请求的JSP页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用jQuery封装后的Ajax</title>
<script src="jquery-3.6.1.js"></script>
</head>
<body>
<table>
<tr>
<td>用户名:</td> <td><input type="text" name="username" class="username"></td>
</tr>
<tr>
<td>密码:</td> <td><input type="password" name="password" class="password"></td>
</tr>
</table>
<button id="main">登陆验证</button>
<p class="data"></p>
<script>
$('#main').click(() => {
$.ajax({
url:'http://localhost/ajaxServer',
data:{
username:$('.username').val(),
password:$('.password').val()
},
success(login){
if(login === "true"){
$('.data').html("登陆成功!")
}else {
$('.data').html("登陆失败!")
}
}
})
})
</script>
</body>
</html>
响应请求的Servlet类:
package Semester_3.src.AJAX;
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 java.io.IOException;
@WebServlet(name = "ajaxServer" , value = "/ajaxServer")
public class ajaxServer extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
if(username.equals("张三") && password.equals("123456")){
resp.getWriter().write("true");
}else {
resp.getWriter().write("false");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
运行效果:
可以看到我们在输入不同的内容的时候,返回的相应内容也是不同的,并且全程我们的页面都没有刷新,所以我们说Ajax是一个异步请求的过程
简单实例:为了体现我们的Ajax是在页面无刷新的请求过程,我们来做一个案例
案例需求:
当我们输入完用户名之后,判断数据库中是否存在相同的用户名,如果存在则显示已存在,如果不存在则显示不存在可以使用
运行过程:
首先我们看到当我们输入一个已经存在与数据库中的名字的时候,当我们的输入框失去焦点的时候,会出现用户名以存在
代码实现:
数据库数据:
数据库判断:
package Semester_3.src.AJAX;
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 java.io.IOException;
@WebServlet(name = "CheckLoginJquery" , value = "/CheckLoginJquery")
public class CheckLoginJquery extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
String username = req.getParameter("username");
String login = DataSelectQuery.select(username);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write(login);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
数据库查询:
package Semester_3.src.AJAX;
import java.sql.*;
public class DataSelectQuery {
public static String select(String name) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql:///jdbc_demo?serverTimezone=UTC";
String username = "root";
String passwd = "@gaoyang1";
Connection conn = DriverManager.getConnection(url, username, passwd);
String SQL = "select * from user where username = ?";
PreparedStatement stat = conn.prepareStatement(SQL);
stat.setString(1,name);
ResultSet set = stat.executeQuery();
if(set.next()){
return "false";
}else {
return "true";
}
}
public static void main(String[] args) throws Exception {
String s = select("赵六");
System.out.println(s);
}
}
JSP页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆检查</title>
<style>
*{
margin: 0 auto;
}
table{
border: 1px solid black;
text-align: center;
width: 300px;
height: 150px;
}
button{
width: 100px;
}
td{
border: 1px solid black;
}
#prompt{
color: red;
font-weight:bold;
}
</style>
<script src="jquery-3.6.1.js"></script>
</head>
<body>
<form action="/CheckLogin">
<table>
<tr>
<td>用户名:</td>
<td>
<input type="text" name="username" id="in_user">
<!-- 要用行内式写属性写display属性-->
<p id="prompt" style="display: none">用户名已存在!</p>
</td>
</tr>
<tr>
<td>密码:</td> <td><input type="password" name="password"></td>
</tr>
<tr><td colspan="2"><button type="submit">提交</button></td></tr>
</table>
</form>
<script>
$('#in_user').blur(()=>{
$.ajax({
url:'http://localhost/CheckLoginJquery',
data:{
username:$('#in_user').val()
},
success(login){
console.log(login)
if(login == "false"){
$('#prompt').attr('style','display: ;')
}else {
$('#prompt').attr('style','display: none;')
}
}
})
})
</script>
</body>
</html>