Java AJAX 完整教程
目录
- 第一部分:AJAX 基础概念
- 什么是 AJAX?
- AJAX 的工作原理
- 为什么在 Java Web 应用中使用 AJAX?
- 第二部分:原生 JavaScript 实现 AJAX
XMLHttpRequest对象详解- GET 请求示例
- POST 请求示例
- 处理 JSON 数据
fetchAPI 简介 (现代替代方案)
- 第三部分:使用 jQuery 实现 AJAX
- 为什么选择 jQuery?
$.ajax()方法详解$.get()和$.post()快捷方法- 处理服务器返回的 JSON
- 第四部分:后端 Java 实现
- 环境准备: Maven 项目、Tomcat 服务器
- 使用 Servlet: 处理 AJAX 请求并返回数据
- 使用 Jackson/Gson 库: 将 Java 对象转换为 JSON
- 示例: Servlet 返回 JSON 字符串
- 第五部分:综合实战案例
- 案例: 用户名实时校验
- 前端实现 (HTML + jQuery AJAX)
- 后端实现 (Servlet + Jackson)
- 案例: 用户名实时校验
- 第六部分:现代 Java Web 开发
- Spring MVC 框架下的 AJAX
@ResponseBody注解- 返回
JSON对象 - 返回
List或Map
- Spring Boot 框架下的 AJAX
更简洁的实现方式
(图片来源网络,侵删)
- Spring MVC 框架下的 AJAX
- 第七部分:常见问题与最佳实践
- 同源策略 与 CORS 跨域问题
- 安全性考虑 (XSS, CSRF)
- 错误处理
- 加载状态提示
第一部分:AJAX 基础概念
什么是 AJAX?
AJAX (Asynchronous JavaScript and XML) 不是一门新的编程语言,而是一种使用现有技术组合,创建快速、动态网页的技术,它的核心是允许网页在不重新加载整个页面的情况下,与服务器进行数据交换并更新部分网页内容。
- Asynchronous (异步): 用户可以在等待服务器响应时继续与页面交互,无需刷新。
- JavaScript: 编写 AJAX 逻辑的语言。
- And (和): 连接词。
- XML (可扩展标记语言): 早期用于数据交换的格式,现在更多地被 JSON 取代。
AJAX 的工作原理
传统网页交互:用户操作 -> 发送请求 -> 服务器处理 -> 返回整个新页面 -> 浏览器渲染整个页面
AJAX 网页交互:用户操作 -> JavaScript 发送异步请求 -> 服务器处理 -> 返回数据 (通常是 JSON/XML) -> JavaScript 更新页面局部内容
为什么在 Java Web 应用中使用 AJAX?
- 提升用户体验: 页面响应更快,操作更流畅,无需等待页面刷新。
- 减少带宽消耗: 只传输必要的数据,而不是整个 HTML 页面。
- 提高服务器性能: 服务器无需处理整个页面的渲染,只需提供数据。
- 实现复杂交互: 如实时搜索、表单自动保存、动态加载数据等。
第二部分:原生 JavaScript 实现 AJAX
虽然现在很多项目使用框架封装的 AJAX 方法,但理解原生 XMLHttpRequest (XHR) 的工作原理至关重要。

XMLHttpRequest 对象详解
这是 AJAX 的核心对象,用于在后台与服务器交换数据。
// 1. 创建 XHR 对象
var xhr;
if (window.XMLHttpRequest) {
// 现代浏览器 (IE7+, Firefox, Chrome, Safari, Opera)
xhr = new XMLHttpRequest();
} else {
// IE6 及以下
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 2. 设置请求方法和 URL
// true 表示异步请求
xhr.open('GET', 'your-servlet-url?param1=value1', true);
// 3. 设置回调函数,用于处理服务器响应
xhr.onreadystatechange = function() {
// readyState 状态说明:
// 0: 请求未初始化
// 1: 服务器连接已建立
// 2: 请求已接收
// 3: 请求处理中
// 4: 请求已完成,且响应已就绪
if (xhr.readyState == 4) {
// status 状态码:
// 200: "OK"
// 404: "Not Found"
// 500: "Internal Server Error"
if (xhr.status == 200) {
// 服务器返回的数据
var response = xhr.responseText;
console.log("服务器返回:", response);
// 在这里更新你的页面 DOM
} else {
console.error("请求出错, 状态码: " + xhr.status);
}
}
};
// 4. 发送请求
// GET 请求的参数可以直接在 URL 中,send() 为 null
// POST 请求的参数作为 send() 的参数
xhr.send(null);
GET 请求示例
// 假设有一个输入框 <input type="text" id="usernameInput">
// 和一个显示结果的 <div id="resultDiv">
document.getElementById('usernameInput').addEventListener('keyup', function() {
var username = this.value;
if (username.length < 2) { // 简单的防抖
return;
}
var xhr = new XMLHttpRequest();
xhr.open('GET', '/checkUsername?username=' + encodeURIComponent(username), true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById('resultDiv').innerText = xhr.responseText;
}
};
xhr.send();
});
POST 请求示例
POST 请求需要设置请求头 Content-Type,并将数据作为参数传递给 send()。
var xhr = new XMLHttpRequest();
xhr.open('POST', '/your-post-servlet', true);
// 设置 Content-Type,告诉服务器发送的是表单数据
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var data = 'username=john&password=123456';
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
// 发送数据
xhr.send(data);
处理 JSON 数据
服务器通常返回 JSON 格式的数据,前端需要使用 JSON.parse() 将其转换为 JavaScript 对象。
// ... 在 xhr.onreadystatechange 回调中
if (xhr.readyState == 4 && xhr.status == 200) {
var responseText = xhr.responseText;
var responseObject = JSON.parse(responseText);
console.log(responseObject.name); // 访问对象属性
console.log(responseObject.age);
}
fetch API 简介
fetch 是现代浏览器提供的一个更强大、更简洁的 AJAX API,它返回一个 Promise。

fetch('/api/user/1')
.then(response => {
// response.json() 也是一个 Promise,用于解析 JSON
return response.json();
})
.then(data => {
console.log(data.name);
})
.catch(error => {
console.error('请求失败:', error);
});
第三部分:使用 jQuery 实现 AJAX
jQuery 大大简化了 AJAX 操作,提供了跨浏览器兼容的统一接口。
为什么选择 jQuery?
- 语法简洁: 代码量更少,可读性更高。
- 浏览器兼容: 无需关心不同浏览器之间的差异。
- 链式调用: 方便地调用多个方法。
$.ajax() 方法详解 (最强大)
这是 jQuery AJAX 的核心方法,可以配置所有选项。
$.ajax({
url: '/checkUsername', // 请求的 URL
type: 'GET', // 请求类型 GET/POST
data: { username: $('#usernameInput').val() }, // 发送到服务器的数据
dataType: 'json', // 预期服务器返回的数据类型 (json, text, html等)
success: function(response) {
// 请求成功时的回调函数
// response 已经被自动解析为 JavaScript 对象 (因为设置了 dataType)
$('#resultDiv').text(response.message);
},
error: function(xhr, status, error) {
// 请求失败时的回调函数
console.error("AJAX Error: " + status + ", " + error);
$('#resultDiv').text('发生错误,请稍后重试。');
},
beforeSend: function(xhr) {
// 发送请求前可以执行的操作,比如显示加载动画
$('#resultDiv').text('正在校验...');
}
});
$.get() 和 $.post() 快捷方法
对于简单的 GET/POST 请求,可以使用更简洁的快捷方法。
// $.get() 示例
$.get('/checkUsername', { username: 'john' }, function(response) {
console.log(response);
}, 'json'); // 第四个参数指定返回类型
// $.post() 示例
$.post('/submitForm', { name: 'John', email: 'john@example.com' }, function(response) {
console.log('提交成功:', response);
});
第四部分:后端 Java 实现
后端需要接收 AJAX 请求并返回数据,在现代 Java Web 开发中,返回 JSON 是最常见的需求。
环境准备
- 创建一个 Maven Web 项目。
- 配置
pom.xml,添加 Servlet 和 JSON 处理库的依赖。
<dependencies>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Jackson: 用于将 Java 对象转换为 JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
</dependencies>
使用 Servlet 处理 AJAX 请求
创建一个 Servlet 来处理前端的请求。
// UserCheckServlet.java
@WebServlet("/checkUsername")
public class UserCheckServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
// 模拟业务逻辑
boolean isAvailable = true;
if ("admin".equalsIgnoreCase(username) || "john".equalsIgnoreCase(username)) {
isAvailable = false;
}
// 准备返回给客户端的数据
String resultMessage;
if (username == null || username.isEmpty()) {
resultMessage = "用户名不能为空";
} else if (isAvailable) {
resultMessage = "用户名 '" + username + "' 可用";
} else {
resultMessage = "用户名 '" + username + "' 已被占用";
}
// 1. 设置响应内容类型为 text/plain 或 application/json
// 如果返回纯文本
response.setContentType("text/plain;charset=UTF-8");
// 如果返回 JSON (推荐)
// response.setContentType("application/json;charset=UTF-8");
// 2. 获取输出流
PrintWriter out = response.getWriter();
// 3. 将数据写入响应流
// 如果返回纯文本
out.write(resultMessage);
// 如果返回 JSON (需要 Jackson)
/*
Map<String, Object> responseData = new HashMap<>();
responseData.put("available", isAvailable);
responseData.put("message", resultMessage);
// 使用 ObjectMapper 将 Map 转换为 JSON 字符串
ObjectMapper mapper = new ObjectMapper();
String jsonResponse = mapper.writeValueAsString(responseData);
out.write(jsonResponse);
*/
}
}
使用 Jackson/Gson 库
手动拼接 JSON 字符串很麻烦且容易出错,Jackson 或 Gson 可以轻松地将 Java 对象/Map/List 转换为 JSON 字符串。
使用 Jackson (如上代码所示):
ObjectMapper mapper = new ObjectMapper(); // 将 Java 对象转成 JSON 字符串 String json = mapper.writeValueAsString(yourJavaObject);
第五部分:综合实战案例:用户名实时校验
前端实现 (HTML + jQuery AJAX)
创建一个 index.html 文件。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">AAX 用户名校验</title>
<!-- 引入 jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>用户注册</h1>
<form>
<div>
<label for="username">用户名:</label>
<input type="text" id="username" name="username">
<!-- 用于显示校验结果 -->
<span id="username-status" style="margin-left: 10px; color: red;"></span>
</div>
<br>
<div>
<label for="password">密码:</label>
<input type="password" id="password" name="password">
</div>
<br>
<button type="submit">注册</button>
</form>
<script>
$(document).ready(function() {
$('#username').on('input', function() { // 使用 input 事件可以捕获粘贴等
var username = $(this).val().trim();
var $statusSpan = $('#username-status');
if (username.length === 0) {
$statusSpan.text('');
return;
}
// 发送 AJAX 请求
$.ajax({
url: 'checkUsername', // 相对路径,会自动加上应用上下文
type: 'GET',
data: { username: username },
dataType: 'json', // 告诉 jQuery 我们期望返回 JSON
success: function(response) {
// response 是一个 JavaScript 对象
$statusSpan.text(response.message);
if (response.available) {
$statusSpan.css('color', 'green');
} else {
$statusSpan.css('color', 'red');
}
},
error: function() {
$statusSpan.text('校验时发生错误。');
$statusSpan.css('color', 'orange');
}
});
});
});
</script>
</body>
</html>
后端实现 (Servlet + Jackson)
确保你的 UserCheckServlet 能返回 JSON 数据。
// UserCheckServlet.java (修改版)
@WebServlet("/checkUsername")
public class UserCheckServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
Map<String, Object> result = new HashMap<>();
if (username == null || username.isEmpty()) {
result.put("available", false);
result.put("message", "用户名不能为空");
} else if ("admin".equalsIgnoreCase(username)) {
result.put("available", false);
result.put("message", "用户名 'admin' 已被占用");
} else {
result.put("available", true);
result.put("message", "用户名 '" + username + "' 可用");
}
// 设置响应头
resp.setContentType("application/json;charset=UTF-8");
// 使用 Jackson 转换并写出
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(resp.getWriter(), result);
}
}
运行你的 Tomcat 服务器,访问 index.html,在用户名输入框中输入内容,就能看到实时的校验反馈了。
第六部分:现代 Java Web 开发
在现代框架中,处理 AJAX 变得异常简单。
Spring MVC 框架下的 AJAX
Spring MVC 提供了 @ResponseBody 注解,可以直接将方法返回的 Java 对象序列化为 JSON 并写入响应体。
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class AjaxController {
@GetMapping("/checkUsernameSpring")
@ResponseBody // 关键注解,表示返回的不是视图,而是直接写入响应体的数据
public Map<String, Object> checkUsername(@RequestParam("username") String username) {
Map<String, Object> result = new HashMap<>();
// ... 业务逻辑 ...
if ("admin".equalsIgnoreCase(username)) {
result.put("available", false);
result.put("message", "用户名已存在");
} else {
result.put("available", true);
result.put("message", "用户名可用");
}
// Spring 会自动配置的 JacksonHttpMessageConverter 将这个 Map 转换成 JSON
return result;
}
}
注意: Spring Boot 默认已经集成了 Jackson,无需额外配置。
Spring Boot 框架下的 AJAX
Spring Boot 是 Spring MVC 的超集,实现方式完全一样,但配置更少,上面的 Spring MVC 代码几乎可以直接在 Spring Boot 项目中运行,只需添加 spring-boot-starter-web 依赖即可。
第七部分:常见问题与最佳实践
同源策略 与 CORS 跨域问题
- 问题: 浏览器出于安全考虑,禁止脚本向不同源(不同协议、域名或端口)的服务器发起 AJAX 请求。
- 解决方案 (CORS): 后端服务器需要响应一个特定的 HTTP 头,告诉浏览器:“我允许这个源的网页来访问我的资源”。
- 在 Servlet 中:
resp.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); // 允许的源 // 如果允许所有源 // resp.setHeader("Access-Control-Allow-Origin", "*"); - 在 Spring Boot 中:
可以通过配置
WebMvcConfigurer或使用@CrossOrigin注解来实现。@RestController @CrossOrigin(origins = "http://localhost:8080") // 对该控制器下的所有方法生效 public class MyAjaxController { // ... }
- 在 Servlet 中:
安全性考虑
- XSS (跨站脚本攻击): 不要直接将用户输入的内容插入到 HTML 中,使用
textContent而不是innerHTML,或者对 HTML 特殊字符进行转义,jQuery 的.text()方法是安全的。 - CSRF (跨站请求伪造): 对于修改状态的 POST/PUT/DELETE 请求,需要使用 CSRF Token 进行防护,Spring Security 等框架提供了内置的 CSRF 保护机制。
错误处理
始终为 AJAX 请求编写 error 回调函数,处理网络错误、服务器错误 (5xx) 和客户端错误 (4xx),并向用户友好的提示。
加载状态提示
在发送请求前(beforeSend)显示一个加载动画或“加载中...”的文本,在请求完成后(success 或 error)将其隐藏,提升用户体验。
本教程涵盖了从 AJAX 基础到 Java 后端实现的完整流程。
- 对于初学者: 建议从 原生 JavaScript 和 Servlet + Jackson 开始,深入理解其工作原理。
- 对于实际项目: 强烈推荐使用 jQuery (或现代框架如 Vue/React 的封装方法) 和 Spring Boot,它们能极大地提高开发效率和代码质量。
掌握 AJAX 是成为一名优秀前端或全栈开发者的必备技能,希望这份教程对你有帮助!
