项目概述
本案例基于 Spring Boot 与 jQuery 构建前后端分离的图书管理系统,重点演示从接口设计到前端联调的完整流程。我们将实现用户登录验证及图书列表展示功能,并深入探讨开发中常见的请求方式差异问题。
核心接口设计
1. 数据模型定义
首先定义后端实体类 BookInfo,用于映射图书信息。注意字段命名需与实际业务保持一致。
@Data
public class BookInfo {
// 图书 ID
private Integer id;
// 书名
private String bookName;
// 作者
private String author;
// 数量
private Integer count;
// 定价
private BigDecimal price;
// 出版社
private String publish;
// 状态 0-不允许借阅 1-允许借阅
private Integer status;
private String statusCN;
// 创建时间
private Date createTime;
// 更新时间
private Date updateTime;
}
2. 登录接口实现
使用 UserController 处理用户认证逻辑,通过 Session 维持会话状态。
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/user")
@RestController
public class UserController {
@RequestMapping("login")
public boolean login(String name, String password, HttpSession session) {
// 基础参数校验
if (!StringUtils.hasLength(name) || !StringUtils.hasLength(password)) {
return false;
}
// 模拟账号密码验证
if ("admin".equals(name) && "admin".equals(password)) {
session.setAttribute("userName", name);
return true;
}
return false;
}
}
3. 图书列表接口与 Mock 数据
在正式接入数据库前,使用 Mock 方法生成模拟数据以推进前端开发。将 Mock 逻辑封装为独立方法,便于后续替换。
@RequestMapping("/book")
@RestController
public class BookController {
@RequestMapping("/getList")
public List<BookInfo> getList() {
List<BookInfo> books = mockData();
// 处理页面展示状态文案
for (BookInfo book : books) {
if (book.getStatus() == 1) {
book.setStatusCN("可借阅");
} else {
book.setStatusCN("不可借阅");
}
}
return books;
}
/**
* 数据 Mock 获取
*/
public List<BookInfo> mockData() {
List<BookInfo> books = new ArrayList<>();
for (int i = 0; i < 15; i++) {
BookInfo book = new BookInfo();
book.setId(i);
book.setBookName("图书" + i);
book.setAuthor("作者" + i); // 统一字段名为 author
book.setCount(new Random().nextInt(100));
book.setPrice(new BigDecimal(new Random().nextInt(100)));
book.setPublish("出版社" + i);
book.setStatus(i % 5 == 0 ? 2 : 1);
books.add(book);
}
return books;
}
}
前端交互实现
1. 登录逻辑
引入 jQuery 库,通过 AJAX 发送 POST 请求至后端登录接口。
<script src="js/jquery.min.js"></script>
<script>
function login() {
$.ajax({
type: "post",
url: "/user/login",
data: {
name: $("#userName").val(),
password: $("#password").val()
},
success: function (result) {
if (result) {
location.href = "book_list.html";
} else {
alert("账号或密码不正确!");
}
}
});
}
</script>
2. 列表渲染
移除前端硬编码数据,改为动态请求后端接口并渲染表格。
function getBookList() {
var finalHtml = "";
$.ajax({
type: "get",
url: "/book/getList",
success: function (result) {
console.log(result);
if (result != null) {
for (var book of result) { // 修复语法错误
finalHtml += "<tr><td><input type='checkbox' name='selectBook' value='" + book.id + "'></td>";
finalHtml += "<td>" + book.id + "</td>";
finalHtml += "<td>" + book.bookName + "</td>";
finalHtml += "<td>" + book.author + "</td>";
finalHtml += "<td>" + book.count + "</td>";
finalHtml += "<td>" + book.price + "</td>";
finalHtml += "<td>" + book.publish + "</td>";
finalHtml += "<td><div>" + book.statusCN + "</div></td>";
finalHtml += "<td><a href='book_update.html?bookId=" + book.id + "'>修改</a>";
finalHtml += "<a href='javascript:void(0)' onclick='deleteBook(" + book.id + ")'>删除</a></td>";
finalHtml += "</tr>";
}
$("tbody").html(finalHtml);
}
}
});
}
调试与排查思路
当接口调用失败时,建议按以下步骤排查:
- 检查后端日志:确认请求是否到达服务器,打印接收到的参数值。
- 验证响应结果:使用 Postman 等工具直接测试接口,确保返回数据结构正确。
- 对比前端代码:检查 AJAX 配置中的 URL、Method 及 Data 格式是否与后端约定一致。
GET 与 POST 请求深度解析
在实际开发中,GET 和 POST 的区别主要体现在参数位置和数据格式约定上,而非简单的传参能力。
1. 参数位置差异
- GET:参数只能放在 URL 中(Query String)。这种方式简单直观,但受 URL 长度限制,且参数暴露在地址栏,不适合传输敏感信息。
- POST:参数既可以放在 URL,也可以放在 Body 中。实际开发中最常用的是 Body 传参,适合传输大量数据或敏感信息。
2. 数据格式一致性
这是前后端联调中最容易出问题的地方。
- GET:由于参数在 URL,后端只需解析 Query String,不存在复杂的格式解析问题。
- POST:若参数放在 Body 中,必须保证前后端对 Content-Type 的约定一致。例如前端发送 JSON,后端必须按 JSON 解析;前端发送 form-data,后端也需对应接收。否则会出现'前端传了,后端收不到'的经典问题。
3. 语义与安全性
- 幂等性:GET 通常用于获取资源,是幂等的(多次请求结果一致);POST 用于提交资源,非幂等。
- 缓存机制:浏览器和 CDN 通常会缓存 GET 请求,而 POST 请求默认不缓存。
- 规范约束:虽然 HTTP 协议理论上允许 GET 携带 Body,但主流客户端(如 Postman)和中间件(如 Nginx)往往忽略 GET 的 Body 部分,这会导致兼容性问题。因此,应严格遵守规范,避免在 GET 请求中使用 Body。
通过遵循上述规范,可以有效减少前后端对接时的沟通成本,提升系统稳定性。

