Spring Boot 前后端联调3大经典案例:从入门到实战(通俗易懂版)

文章目录

    • 前言
    • 案例一:表单提交与参数绑定(简单求和计算器)
      • [1. 后端实现:CalcController.java](#1. 后端实现:CalcController.java)
      • [2. 前端实现:calc.html](#2. 前端实现:calc.html)
      • [3. 核心知识点:参数绑定(入门关键)](#3. 核心知识点:参数绑定(入门关键))
    • [案例二:AJAX 异步交互与 Session 状态管理(用户登录系统)](#案例二:AJAX 异步交互与 Session 状态管理(用户登录系统))
      • [1. 后端实现:UserController.java](#1. 后端实现:UserController.java)
      • [2. 前端实现:登录页(login.html)+ 首页(index.html)](#2. 前端实现:登录页(login.html)+ 首页(index.html))
      • [3. 核心知识点:AJAX 与 Session 状态保持](#3. 核心知识点:AJAX 与 Session 状态保持)
    • [案例三:JSON 数据传输与 RESTful 接口(留言板系统)](#案例三:JSON 数据传输与 RESTful 接口(留言板系统))
      • [1. 后端实现:实体类 + MessageController](#1. 后端实现:实体类 + MessageController)
      • [2. 前端实现:message.html](#2. 前端实现:message.html)
      • [3. 核心知识点:JSON 数据交互(现代Web开发核心)](#3. 核心知识点:JSON 数据交互(现代Web开发核心))
    • 总结:3种前后端联调模式对比(清晰易懂)
    • 写在最后

前言

作为Spring Boot初学者,跨过「后端接口编写」到「前后端数据交互」的鸿沟,是掌握Web开发的关键一步。很多新手都会陷入困惑:前端表单数据如何准确传递到后端?怎样实现无刷新页面的用户登录?复杂的业务数据该用什么格式高效传输?

本文将通过3个由浅入深、可直接运行的经典案例,手把手带大家攻克Spring Boot前后端联调的核心难点。从最基础的表单求和,到无刷新AJAX登录,再到主流的JSON留言板,层层递进讲解核心注解、数据绑定、状态管理等关键技术,零基础也能轻松看懂并落地。

案例一:表单提交与参数绑定(简单求和计算器)

这是最传统、最基础的Web交互方式,无需任何JavaScript代码,通过HTML表单直接提交数据,非常适合入门理解「参数绑定」的核心概念,搭建前后端交互的基本认知。

1. 后端实现:CalcController.java

使用@RestController注解简化接口编写,无需返回视图页面,直接将计算结果以字符串形式响应给前端。

java 复制代码
package cn.overthinker.springboot;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

// 注解说明:@RestController = @Controller + @ResponseBody,直接返回数据(不跳转页面)
@RequestMapping("/calc") // 统一前缀,所有该控制器的接口都以/calc开头
@RestController
public class CalcController {

    /**
     * 求和接口:接收前端表单提交的两个数字,返回计算结果
     * 核心:方法参数名与前端表单name属性自动绑定
     */
    @RequestMapping("/sum") // 接口完整路径:/calc/sum
    public String sum(Integer num1, Integer num2) {
        // 非空判断:使用Integer包装类避免空指针异常(前端输入为空时,参数为null而非0)
        if(num1 == null || num2 == null) {
            return "请求非法:请输入两个有效的数字!";
        }
        
        // 计算并返回结果,Spring Boot自动将字符串响应给前端
        return "计算结果为:" + (num1 + num2);
    }
}

2. 前端实现:calc.html

编写简单HTML表单,通过form标签的action属性指定后端接口地址,method属性指定请求提交方式,完成数据传递。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单求和计算器</title>
    <style>
        body { font-family: sans-serif; background-color: #f4f7f6; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }
        .calculator-container { background-color: #ffffff; padding: 40px; border-radius: 12px; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1); width: 300px; text-align: center; }
        h1 { color: #333; margin-bottom: 30px; font-size: 24px; border-bottom: 2px solid #5cb85c; display: inline-block; padding-bottom: 5px; }
        input[type="text"] { width: 100%; padding: 10px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; }
        input[type="submit"] { background-color: #5cb85c; color: white; padding: 12px 20px; border: none; border-radius: 6px; cursor: pointer; font-size: 16px; margin-top: 20px; width: 100%; transition: background-color 0.3s ease; }
        input[type="submit"]:hover { background-color: #4cae4c; }
    </style>
</head>
<body>
    <div class="calculator-container">
        <h1>简单求和计算器</h1>
        <!-- 表单核心配置:action指定后端接口,method指定提交方式 -->
        <form action="/calc/sum" method="post">
            数字1:<input name="num1" type="text" placeholder="请输入数字1"><br>
            数字2:<input name="num2" type="text" placeholder="请输入数字2"><br>
            <input type="submit" value=" 点击相加 ">
        </form>
    </div>
</body>
</html>

3. 核心知识点:参数绑定(入门关键)

  1. 名字必须完全一致 :前端<input name="num1">中的name属性值,必须和后端方法参数Integer num1的参数名完全匹配(大小写敏感),Spring Boot才能自动完成表单数据到后端参数的赋值。
  2. 自动类型转换 :前端表单提交的所有数据本质上都是「字符串」,而后端接收的是Integer类型,Spring Boot会自动完成「字符串→整数」的类型转换,无需手动编写转换逻辑。
  3. 运行效果:填写两个有效数字后点击「相加」,页面会刷新并直接展示后端返回的计算结果,直观看到前后端数据交互的结果。

案例二:AJAX 异步交互与 Session 状态管理(用户登录系统)

传统表单提交会刷新整个页面,用户体验较差。而AJAX可以实现「无刷新异步通信」,仅更新页面局部内容,同时结合Session实现服务器端的用户状态保持,这是登录、用户中心等功能的核心实现方式。

1. 后端实现:UserController.java

提供登录接口和获取当前登录用户接口,使用HttpSession存储用户登录状态,实现跨页面的登录信息保持。

java 复制代码
package cn.overthinker.springboot;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/user") // 接口统一前缀:/user
@RestController
public class UserController {

    /**
     * 登录接口:接收用户名和密码,验证通过后存入Session
     * @param userName 前端传递的用户名
     * @param password 前端传递的密码
     * @param session  HttpSession,用于存储用户状态(Spring Boot自动注入)
     * @return 验证结果:true成功,false失败
     */
    @PostMapping("/login") // 接口路径:/user/login,仅接收POST请求
    public boolean login(String userName, String password, HttpSession session) {
        // 参数校验:判断用户名和密码是否为空(使用Spring的StringUtils工具类)
        if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
            return false;
        }

        // 硬编码校验(实际项目中应查询数据库,此处为简化演示)
        if("admin".equals(userName) && "123456".equals(password)) {
            // 核心:登录成功后,将用户名存入Session(键值对形式,键可自定义)
            session.setAttribute("loginUser", userName);
            return true;
        }

        return false;
    }

    /**
     * 获取当前登录用户接口:从Session中读取已存储的用户信息
     */
    @GetMapping("/getLoginUser") // 接口路径:/user/getLoginUser,仅接收GET请求
    public String getLoginUser(HttpServletRequest request) {
        // 关键:request.getSession(false) - 如果Session不存在,不创建新Session,直接返回null
        // 避免未登录时创建无用的Session
        HttpSession session = request.getSession(false);
        if(session != null) {
            // 从Session中根据键获取值,强转为String类型
            String loginUser = (String) session.getAttribute("loginUser");
            return loginUser;
        }
        // 未登录或Session失效时,返回空字符串
        return "";
    }
}

2. 前端实现:登录页(login.html)+ 首页(index.html)

使用jQuery简化AJAX编写(直接引入CDN,无需本地配置环境),实现无刷新登录验证和登录状态展示。

(1)登录页:login.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>用户登录</title>
  <style>
    body { font-family: sans-serif; background-color: #e8eff1; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }
    .login-box { background-color: #fff; padding: 40px; border-radius: 8px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); width: 280px; text-align: center; }
    h1 { color: #3c8dbc; margin-bottom: 25px; }
    input[type="text"], input[type="password"] { width: 100%; padding: 10px; margin-bottom: 15px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; }
    input[type="button"] { background-color: #3c8dbc; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; width: 100%; transition: background-color 0.3s; }
    input[type="button"]:hover { background-color: #367fa9; }
  </style>
</head>
<body>
  <div class="login-box">
    <h1>用户登录</h1>
    用户名:<input name="userName" type="text" id="userName" placeholder="请输入用户名"><br>
    密码:<input name="password" type="password" id="password" placeholder="请输入密码"><br>
    <input type="button" value="登录" onclick="login()">
  </div>

  <!-- 引入jQuery CDN,简化AJAX编写 -->
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
  <script>
    // 登录按钮点击事件:触发AJAX请求
    function login() {
      $.ajax({
        url: "/user/login", // 后端登录接口地址
        type: "post", // 请求方式:与后端@PostMapping对应
        // 核心:传递参数(键值对形式,键与后端参数名一致)
        data: {
          userName: $("#userName").val(), // 获取用户名输入框的值
          password: $("#password").val()  // 获取密码输入框的值
        },
        // 回调函数:后端返回结果后执行
        success: function (result) {
          if (result) {
            // 登录成功:跳转到首页(无刷新仅针对当前请求,跳转页面是正常业务逻辑)
            location.href = "/index.html";
          } else {
            // 登录失败:弹出提示框(页面不刷新)
            alert("用户名或密码错误!");
          }
        }
      });
    }
  </script>
</body>
</html>
(2)首页:index.html(展示登录状态)
html 复制代码
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录首页</title>
    <style>
        body { font-family: sans-serif; background-color: #f0f4f7; padding: 50px; }
        .welcome { font-size: 24px; color: #333; }
        #loginUser { color: #d9534f; font-weight: bold; }
    </style>
</head>
<body>
    <div class="welcome">欢迎回来,登录人: <span id="loginUser"></span></div>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        // 页面加载完成后,自动发起AJAX请求获取登录用户信息
        $.ajax({
            url: "user/getLoginUser", // 后端获取登录用户接口
            type: "get", // 请求方式:与后端@GetMapping对应
            success: function (userName) {
                // 将后端返回的用户名显示在页面上(无刷新更新局部内容)
                $("#loginUser").text(userName || "(未登录)");
            }
        });
    </script>
</body>
</html>

3. 核心知识点:AJAX 与 Session 状态保持

  1. AJAX 核心优势:异步通信、无刷新页面,仅更新局部内容,大幅提升用户体验。通俗理解:AJAX就是前端在后台偷偷给后端发请求,后端偷偷返回结果,整个过程页面不会刷新,用户操作不会被中断。
  2. Session 工作机制(通俗版)
    • 登录成功时,后端session.setAttribute("loginUser", userName)会在服务器端创建一个「用户专属会话」,并生成一个唯一的「Session ID」。
    • 服务器会将「Session ID」通过Cookie发送给浏览器,浏览器会自动保存这个Cookie(无需前端手动处理)。
    • 当用户访问首页,发起/user/getLoginUser请求时,浏览器会自动携带「Session ID」发送给服务器。
    • 服务器通过「Session ID」找到对应的「用户专属会话」,从而取出存入的loginUser,实现「登录状态保持」(即使跳转页面,登录状态也不会丢失)。
  3. 关键注解补充@PostMapping@GetMapping@RequestMapping的简化版,分别限定接口仅接收POST、GET请求,更符合RESTful风格,安全性更高,也是实际项目中的主流用法。

案例三:JSON 数据传输与 RESTful 接口(留言板系统)

前面两个案例适合传输简单的单个参数,而实际项目中经常需要传输复杂数据(如对象、列表、嵌套数据),此时JSON格式是最优选择,这也是现代Web开发的主流数据传输方式。

1. 后端实现:实体类 + MessageController

(1)实体类:MessageInfo.java(数据传输对象 DTO)

用于封装留言数据,使用Lombok的@Data注解自动生成Getter/Setter、toString等方法,简化代码编写,减少冗余。

java 复制代码
package cn.overthinker.springboot;

import lombok.Data;

// 注解说明:@Data 自动生成所有属性的Getter、Setter、toString、equals等方法
@Data
public class MessageInfo {
    // 留言人
    private String from;
    // 接收人
    private String to;
    // 留言内容
    private String message;
}
(2)控制器:MessageController.java

提供发布留言和获取留言列表接口,使用@RequestBody接收JSON格式数据,返回JSON格式列表,符合RESTful接口规范。

java 复制代码
package cn.overthinker.springboot;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;

@RequestMapping("/message") // 接口统一前缀:/message(建议小写,符合RESTful规范)
@RestController
public class MessageController {

    // 模拟数据库:存储所有留言(内存存储,项目重启后数据丢失)
    private List<MessageInfo> messageInfoList = new ArrayList<>();

    /**
     * 发布留言接口:接收前端传递的JSON格式留言数据
     * 核心:@RequestBody 注解将请求体中的JSON数据映射为Java对象
     */
    @PostMapping("/publish") // 接口路径:/message/publish
    public Boolean publish(@RequestBody MessageInfo messageInfo) {
        // 参数校验:判断留言人、接收人、留言内容是否为空
        if(!StringUtils.hasLength(messageInfo.getFrom())
                || !StringUtils.hasLength(messageInfo.getTo())
                || !StringUtils.hasLength(messageInfo.getMessage())) {
            return false;
        }
        // 保存留言到模拟数据库
        messageInfoList.add(messageInfo);
        return true;
    }

    /**
     * 获取留言列表接口:返回JSON格式的留言列表
     * 核心:Spring Boot自动将List对象转换为JSON数组响应给前端
     */
    @GetMapping("/getList") // 接口路径:/message/getList
    public List<MessageInfo> getList() {
        // 直接返回List对象,Spring Boot自动完成对象→JSON数组的转换
        return messageInfoList;
    }
}

2. 前端实现:message.html

发送JSON格式数据到后端,接收并展示后端返回的JSON留言列表,实现无刷新发布和展示留言,还原真实项目中的数据交互场景。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>留言板</title>
    <style>
        body { font-family: sans-serif; background-color: #f0f7f4; padding: 20px; }
        .container { width: 400px; margin: 20px auto; background-color: #fff; padding: 25px; border-radius: 10px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08); text-align: center; }
        h1 { color: #387063; margin-bottom: 5px; }
        .grey { color: #888; margin-bottom: 20px; }
        .row { display: flex; justify-content: space-between; align-items: center; height: 40px; margin-bottom: 10px; }
        .row span { width: 70px; text-align: left; color: #555; font-weight: bold; }
        .row input { flex-grow: 1; height: 35px; padding: 5px 10px; border: 1px solid #ddd; border-radius: 4px; }
        #submit { width: 100%; height: 45px; background-color: #387063; color: white; border: none; border-radius: 5px; margin-top: 20px; font-size: 18px; cursor: pointer; transition: background-color 0.3s; }
        #submit:hover { background-color: #2b574d; }
        .message-list div { text-align: left; padding: 8px 0; border-bottom: 1px dashed #eee; color: #333; }
    </style>
</head>
<body>
    <div class="container">
        <h1>留言板</h1>
        <p class="grey">输入后点击提交,信息将显示在下方</p>
        <div class="row">
            <span>谁:</span> <input type="text" id="from" placeholder="你的名字">
        </div>
        <div class="row">
            <span>对谁:</span> <input type="text" id="to" placeholder="你想对谁说">
        </div>
        <div class="row">
            <span>说什么:</span> <input type="text" id="say" placeholder="你的留言内容">
        </div>
        <input type="button" value="提交留言" id="submit" onclick="submit()">
        
        <div class="message-list"></div>
    </div>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        // 页面加载时,自动获取并展示所有留言
        function loadMessages() {
            $.ajax({
                type: "get",
                url: "/message/getList",
                success: function (messages) {
                    $(".message-list").empty(); // 清空旧的留言列表,避免重复展示
                    // 遍历后端返回的JSON数组,拼接HTML并展示
                    for (let msg of messages) {
                        let div = "<div>" + msg.from + " 对 " + msg.to + " 说: " + msg.message + "</div>";
                        $(".message-list").append(div);
                    }
                }
            });
        }
        
        // 初始化:页面加载完成后立即加载留言列表
        loadMessages();

        // 提交留言方法
        function submit() {
            var from = $('#from').val();
            var to = $('#to').val();
            var say = $('#say').val();
            // 简单非空校验
            if (from == '' || to == '' || say == '') {
                alert("请填写完整留言信息!");
                return;
            }

            // 核心:发送JSON格式数据到后端
            $.ajax({
                type: "post",
                url: "/message/publish",
                // 关键1:设置请求头,告诉服务器发送的是JSON格式数据
                contentType: "application/json",
                // 关键2:将JS对象转换为JSON字符串(后端才能解析)
                data: JSON.stringify({
                    from: from,
                    to: to,
                    message: say // 键名与后端MessageInfo实体类的属性名一致
                }),
                success: function (result) {
                    if (result) {
                        // 提交成功:重新加载留言列表 + 清空输入框
                        loadMessages();
                        $('#from').val("");
                        $('#to').val("");
                        $('#say').val("");
                    } else {
                        alert("添加留言失败,请检查输入!");
                    }
                }
            });
        }
    </script>
</body>
</html>

3. 核心知识点:JSON 数据交互(现代Web开发核心)

  1. @RequestBody 注解(后端关键)
    • 作用:告诉Spring Boot「请解析HTTP请求体中的JSON数据,并自动映射到对应的Java实体类对象中」。
    • 注意:如果缺少该注解,Spring Boot无法识别请求体中的JSON格式数据,会导致实体类属性全部为null,无法完成数据绑定。
  2. 前端两个关键配置
    • contentType: "application/json":设置请求头,明确告诉服务器「本次请求的请求体是JSON格式数据」,这是后端能够正确解析JSON的前提条件。
    • JSON.stringify(...):将JavaScript对象转换为JSON字符串,因为HTTP请求只能传输字符串格式数据,无法直接传输JS对象。
  3. JSON 字段匹配 :前端JSON中的键名(如fromtomessage)必须和后端实体类(MessageInfo)的属性名完全一致,Spring Boot才能完成自动映射和数据赋值。
  4. 自动序列化/反序列化
    • 反序列化:后端通过@RequestBody注解,自动将前端传递的「JSON字符串」转换为「Java对象」(MessageInfo)。
    • 序列化:后端返回List<MessageInfo>列表时,Spring Boot自动将「Java列表对象」转换为「JSON数组」,前端可直接遍历使用,无需手动转换格式。

总结:3种前后端联调模式对比(清晰易懂)

联调模式 对应案例 核心特点 后端关键技术 优点 缺点
传统Form表单提交 求和计算器 页面刷新,同步通信 方法参数绑定、@RestController 简单易上手,无需JS 用户体验差,无法局部更新
AJAX(键值对参数) 用户登录系统 无刷新,异步通信,简单参数 @PostMapping/@GetMapping、Session 用户体验好,局部更新 仅适合传输少量简单参数
AJAX(JSON格式数据) 留言板系统 无刷新,异步通信,复杂数据 @RequestBody、实体类、JSON序列化 支持复杂数据,现代主流 配置稍多,需要理解JSON

写在最后

通过本文的3个案例,我们从最基础的表单提交逐步过渡到现代主流的JSON异步交互,掌握了Spring Boot前后端联调的核心技巧和关键注解。

学习前后端联调的核心在于「动手实践」,建议大家亲手运行所有代码,修改参数测试不同场景(比如故意输入非数字、空用户名等),观察后端的响应结果,这样才能真正理解背后的逻辑。

这3种联调模式是后续复杂Web项目开发的基础,掌握它们后,你可以轻松拓展到用户注册、数据分页、文件上传等更复杂的功能,为成为全栈开发者打下坚实基础。

相关推荐
sin22012 小时前
Spring事务管理(SpringBoot)
java·spring boot·spring
BD_Marathon2 小时前
SpringBoot——配置文件格式
java·spring boot·后端
indexsunny2 小时前
互联网大厂Java面试实战:Spring Boot与微服务在电商场景的应用解析
java·spring boot·redis·微服务·kafka·gradle·maven
幽络源小助理2 小时前
SpringBoot+小程序高校素拓分管理系统源码 – 幽络源免费分享
spring boot·后端·小程序
程序员爱钓鱼2 小时前
Node.js 编程实战:测试与调试 —— 日志与监控方案
前端·后端·node.js
雄大2 小时前
使用 QWebChannel 实现 JS 与 C++ 双向通信(超详细 + 踩坑总结 + Demo)
后端
计算机学姐2 小时前
基于SpringBoot的汉服租赁系统【颜色尺码套装+个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·后端·mysql·信息可视化·推荐算法
回家路上绕了弯2 小时前
定期归档历史数据实战指南:从方案设计到落地优化
分布式·后端
+VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue建筑材料管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计