本文纲要

  1. AJAX 概述
    同步与异步交互
  2. AJAX 快速入门
    原生 AJAX 核心对象与步骤
    服务端 AjaxServlet
    前端示例代码
  3. 案例:验证用户名是否存在
    后端 SelectUserServlet
    前端注册页面 register.html
    交互流程与关键代码
  4. Axios 异步框架
    Axios 基本使用
    请求方式别名
    Axios 与 JSON 的自动转换
  5. JSON 数据格式
    基础语法
    JSON 字符串与 JS 对象互转
  6. JSON 与 Java 对象转换
    FastJson API
    User 转换示例
  7. 综合案例:品牌列表查询
    项目结构
    后端 SelectAllServlet
    前端 brand.html 渲染逻辑
  8. 综合案例:新增品牌
    后端 AddServlet
    前端 addBrand.html 表单处理
    JSON 数据传输与接收
  9. 总结

AJAX 概述

AJAX 全称为 Asynchronous JavaScript And XML,即异步的 JavaScript 和 XML。它是一种在不重新加载整个页面的情况下与服务器交换数据并更新部分网页的技术。

1 ) AJAX 的两大核心作用

作用说明
与服务器进行数据交换通过 AJAX 可以给服务器发送请求,并获取服务器响应的数据,进而使用 HTML + AJAX 替代传统的 JSP 页面,实现前后端分离。
异步交互客户端发送请求后不需要等待服务器处理完成,可以继续执行其他操作,用户体验更流畅。典型应用如:搜索联想、用户名唯一性校验。

2 ) 同步与异步对比

同步请求:用户操作会阻塞,等待服务器响应后才能继续操作。
异步请求:请求发送后浏览器不锁死,用户可以继续操作,服务器响应到达后再通过回调处理。

服务器 浏览器 服务器 浏览器 同步请求 期间用户只能等待 异步请求 用户可以继续操作 发送请求 处理中(耗时3秒) 响应 发送异步请求 处理中 响应 回调函数更新局部页面

AJAX 快速入门

原生 AJAX 的核心对象是 XMLHttpRequest,通过它可以与服务器进行异步数据交换。

1 ) 开发步骤

  1. 创建 XMLHttpRequest 对象
  2. 调用 open()方法设置请求方式和 URL
  3. 调用 send() 发送请求
  4. 绑定 onreadystatechange 事件,监听响应状态并处理数据

2 ) 服务端 Servlet

编写一个简单的 AjaxServlet,响应固定字符串。

package com.wb.web.servlet;
 
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
 
@WebServlet("/ajaxServlet")
public class AjaxServlet extends HttpServlet {
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 响应数据 
        response.getWriter().write("hello ajax~");
    }
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

3 )前端 HTML 页面

01-ajax-demo1.html 展示了完整的 AJAX 请求流程。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>AJAX 快速入门</title>
</head>
<body>
<script>
    // 1. 创建核心对象(兼容低版本 IE)
    var xhttp;
    if (window.XMLHttpRequest) {
        xhttp = new XMLHttpRequest();
    } else {
        xhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
 
    // 2. 发送异步请求(建议使用全路径,便于前后端分离)
    xhttp.open("GET", "http://localhost:8080/ajax-demo/ajaxServlet");
    xhttp.send();
 
    // 3. 获取响应数据 
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            alert(this.responseText);  // 弹出 "hello ajax~"
        }
    };
</script>
</body>
</html>

说明:readyState 为 4 表示请求已完成且响应就绪,status 为 200 表示成功。responseText 属性保存服务器返回的文本数据。

案例:验证用户名是否存在

需求:注册页面中,当用户名输入框失去焦点时,立即异步请求后端校验用户名是否已存在,并给出提示。

1 ) 交互流程

SelectUserServlet register.html 用户 SelectUserServlet register.html 用户 输入用户名, 光标离开(onblur) 异步GET请求 username=xxx 响应 "true"(存在) 或 "false"(不存在) 显示/隐藏"用户名已存在"

2 )后端 SelectUserServlet

package com.wb.web.servlet;
 
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
 
@WebServlet("/selectUserServlet")
public class SelectUserServlet extends HttpServlet {
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 1. 接收用户名 
        String username = request.getParameter("username");
 
        // 2. 调用service查询用户对象(此处模拟逻辑,实际应查数据库)
        boolean flag = true;   // true 表示已存在 
 
        // 3. 响应标记 
        response.getWriter().write("" + flag);
    }
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

3 ) 前端 register.html

<script>
    // 1. 给用户名输入框绑定失去焦点事件 
    document.getElementById("username").onblur = function () {
        // 获取输入的用户名 
        var username = this.value;
 
        // 2.1 创建核心对象 
        var xhttp;
        if (window.XMLHttpRequest) {
            xhttp = new XMLHttpRequest();
        } else {
            xhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
 
        // 2.2 发送请求(携带参数)
        xhttp.open("GET", "http://localhost:8080/ajax-demo/selectUserServlet?username=" + username);
        xhttp.send();
 
        // 2.3 获取响应 
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                if(this.responseText == "true"){
                    // 用户名存在,显示提示信息 
                    document.getElementById("username_err").style.display = '';
                } else {
                    // 用户名不存在,隐藏提示 
                    document.getElementById("username_err").style.display = 'none';
                }
            }
        };
    }
</script>

Axios 异步框架

Axios 是对原生 AJAX(XMLHttpRequest)的封装,用于简化异步请求的书写。
它支持 Promise 风格的调用,代码更加简洁。

1 ) Axios 基本使用

两步走:引入 JS 文件 + 调用 axios() 方法。

引入 Axios 库

<script src="js/axios-0.18.0.js"></script>

发送 GET / POST 请求

<script>
    // GET 请求:参数拼在URL后 
    axios({
        method: "get",
        url: "http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan"
    }).then(function (resp) {
        alert(resp.data);  // 响应数据 
    });
 
    // POST 请求:参数通过 data 属性传递 
    axios({
        method: "post",
        url: "http://localhost:8080/ajax-demo/axiosServlet",
        data: "username=zhangsan"
    }).then(function (resp) {
        alert(resp.data);
    });
</script>

对应后端 AxiosServlet

@WebServlet("/axiosServlet")
public class AxiosServlet extends HttpServlet {
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("get...");
        String username = request.getParameter("username");
        System.out.println(username);
        response.getWriter().write("hello Axios~");
    }
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("post...");
        this.doGet(request, response);
    }
}

2 ) 请求方式别名

Axios 还提供了更简洁的别名方法:

// GET 别名 
axios.get("http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan")
     .then(function (resp) {
         alert(resp.data);
     });
 
// POST 别名 
axios.post("http://localhost:8080/ajax-demo/axiosServlet", "username=zhangsan")
     .then(function (resp) {
         alert(resp.data);
     });

注意:使用 axios.post() 时,第二个参数直接放置请求体数据(字符串或对象均可,如果是对象则 Axios 会自动转为 JSON)。

3 ) Axios 自动处理 JSON

当 data 属性传入 JavaScript 对象时,Axios 会自动将其序列化为 JSON 字符串发送,并且设置请求头 Content-Type: application/json。

var jsObject = { name: "zhangsan" };
 
axios({
    method: "post",
    url: "http://localhost:8080/ajax-demo/axiosServlet",
    data: jsObject       // 自动转为 {"name":"zhangsan"}
}).then(function (resp) {
    alert(resp.data);
});

JSON 数据格式

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析。目前已成为前后端数据交互的主流载体。

1 ) JSON 基础语法

JSON 是一段字符串
键必须用双引号包裹,值可以是数字、字符串、布尔值、数组、对象或 null

示例:

{
    "name": "zhangsan",
    "age": 23,
    "addr": ["北京", "上海", "西安"]
}

2 ) JSON 与 JS 对象互转

在浏览器中可以使用内置对象 JSON 进行转换。

<script>
    // 1. 定义 JSON 字符串 
    var jsonStr = '{"name":"zhangsan","age":23,"addr":["北京","上海","西安"]}';
 
    // 2. JSON 字符串 转 JS 对象 
    let jsObject = JSON.parse(jsonStr);
    alert(jsObject.name);   // "zhangsan"
 
    // 3. JS 对象 转 JSON 字符串 
    let jsonStr2 = JSON.stringify(jsObject);
    alert(jsonStr2);
</script>

JSON 与 Java 对象转换

在服务端需要将 Java 对象与 JSON 字符串互相转换,常用库为阿里巴巴的 Fastjson。

1 ) 引入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

2 ) Fastjson 核心 API

方法说明
JSON.toJSONString(Object)Java 对象 → JSON 字符串
JSON.parseObject(String, Class)JSON 字符串 → 指定类型的 Java 对象

3 ) 代码示例

User 实体类

public class User {
    private Integer id;
    private String username;
    private String password;
    // getter & setter & toString 省略...
}

转换测试

import com.alibaba.fastjson.JSON;
 
public class FastJsonDemo {
    public static void main(String[] args) {
        // 1. Java对象 → JSON字符串 
        User user = new User();
        user.setId(1);
        user.setUsername("zhangsan");
        user.setPassword("123");
        String jsonString = JSON.toJSONString(user);
        System.out.println(jsonString);
        // 输出:{"id":1,"password":"123","username":"zhangsan"}
 
        // 2. JSON字符串 → Java对象 
        String json = "{\"id\":1,\"password\":\"123\",\"username\":\"zhangsan\"}";
        User u = JSON.parseObject(json, User.class);
        System.out.println(u);
    }
}

综合案例:品牌列表查询

需求:页面加载完成后,通过 Axios 异步请求后端,查询所有品牌数据并以表格形式展示。

1 ) 项目结构(brand-demo)

brand-demo 
├── pom.xml 
└── src 
    ├── main 
    │   ├── java/com/wb 
    │   │   ├── mapper/BrandMapper.java 
    │   │   ├── pojo/Brand.java 
    │   │   ├── service/BrandService.java 
    │   │   ├── util/SqlSessionFactoryUtils.java 
    │   │   └── web 
    │   │       ├── AddServlet.java 
    │   │       └── SelectAllServlet.java 
    │   ├── resources 
    │   │   ├── mybatis-config.xml 
    │   │   └── com/wb/mapper/BrandMapper.xml 
    │   └── webapp 
    │       ├── addBrand.html 
    │       ├── brand.html 
    │       └── js/axios-0.18.0.js 
    └── test 

2 ) 后端 SelectAllServlet

@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
    private BrandService brandService = new BrandService();
 
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 1. 调用 Service 查询所有品牌 
        List<Brand> brands = brandService.selectAll();
 
        // 2. 将集合转为 JSON 数组 
        String jsonString = JSON.toJSONString(brands);
 
        // 3. 设置响应类型并写出 
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().write(jsonString);
    }
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

3 ) 前端 brand.html 核心逻辑

直接访问 brand.html 后,页面自动请求数据并动态渲染表格。

<script src="js/axios-0.18.0.js"></script>
<script>
    // 页面加载完成事件 
    window.onload = function () {
        // 发送 GET 请求 
        axios({
            method: "get",
            url: "http://localhost:8080/brand-demo/selectAllServlet"
        }).then(function (resp) {
            // resp.data 就是服务器返回的品牌数组 
            let brands = resp.data;
 
            // 拼接表头 
            let tableData = "<tr><th>序号</th><th>品牌名称</th><th>企业名称</th><th>排序</th><th>品牌介绍</th><th>状态</th><th>操作</th></tr>";
 
            // 遍历数据拼接每一行 
            for (let i = 0; i < brands.length; i++) {
                let brand = brands[i];
                tableData += 
                    "<tr align='center'>" +
                    "<td>" + (i + 1) + "</td>" +
                    "<td>" + brand.brandName + "</td>" +
                    "<td>" + brand.companyName + "</td>" +
                    "<td>" + brand.ordered + "</td>" +
                    "<td>" + brand.description + "</td>" +
                    "<td>" + brand.status + "</td>" +
                    "<td><a href='#'>修改</a> <a href='#'>删除</a></td>" +
                    "</tr>";
            }
 
            // 替换原有表格内容 
            document.getElementById("brandTable").innerHTML = tableData;
        });
    };
</script>

效果:页面展示数据库中所有的品牌记录,无刷新动态加载。

综合案例:新增品牌

需求:在新增页面填写表单,点击“提交”后通过 Axios 发送 POST 请求,将 JSON 数据传给后端完成添加,成功后自动跳转到品牌列表页。

1 ) 后端 AddServlet

注意:request.getParameter() 无法接收 JSON 格式的请求体,需要从输入流中读取字符串,再使用 Fastjson 解析。

@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    private BrandService brandService = new BrandService();
 
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 1. 获取请求体中的 JSON 字符串 
        BufferedReader br = request.getReader();
        String params = br.readLine();
 
        // 2. 将 JSON 字符串转为 Brand 对象 
        Brand brand = JSON.parseObject(params, Brand.class);
 
        // 3. 调用 service 添加 
        brandService.add(brand);
 
        // 4. 响应成功标识 
        response.getWriter().write("success");
    }
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }
}

前端 addBrand.html

<script src="js/axios-0.18.0.js"></script>
<script>
    document.getElementById("btn").onclick = function () {
        // 1. 构建 JSON 数据对象 
        var formData = {
            brandName: "",
            companyName: "",
            ordered: "",
            description: "",
            status: ""
        };
 
        // 2. 获取表单数据并填入 
        formData.brandName = document.getElementById("brandName").value;
        formData.companyName = document.getElementById("companyName").value;
        formData.ordered = document.getElementById("ordered").value;
        formData.description = document.getElementById("description").value;
 
        // 处理单选按钮(状态)
        let statusNodes = document.getElementsByName("status");
        for (let i = 0; i < statusNodes.length; i++) {
            if (statusNodes[i].checked) {
                formData.status = statusNodes[i].value;
            }
        }
 
        // 3. 发送 AJAX POST 请求 
        axios({
            method: "post",
            url: "http://localhost:8080/brand-demo/addServlet",
            data: formData   // Axios 自动将对象转为 JSON 字符串 
        }).then(function (resp) {
            if (resp.data == "success") {
                // 4. 添加成功,跳转到列表页 
                location.href = "http://localhost:8080/brand-demo/brand.html";
            }
        });
    };
</script>

关键点:request.getParameter() 适用于普通表单编码或 URL 参数,对于 JSON 请求体必须通过 request.getReader() 手动解析

总结

通过本文的实践,我们掌握了以下核心技术:

  • AJAX 基础:理解同步与异步的区别,掌握原生 XMLHttpRequest 的发送与响应处理。
  • Axios 框架:极大简化异步请求代码,支持 GET/POST 及别名调用,内置 JSON 自动序列化。
  • JSON 数据格式:前后端分离的数据交换标准,学会在 JS 和 Java 中互相转换(Fastjson)。
  • 实战案例:从零实现用户名唯一性校验、品牌列表查询与新增,打通前后端完整交互链路。

这些内容是 JavaWeb 前后端分离开发的基石,也是后续学习 Vue、React 等现代前端框架的重要前置知识。希望读者能结合代码多加练习,夯实基本功。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐