跳到主要内容 基于 Spring Boot 的 Web 三大核心交互案例详解 | 极客日志
Python
基于 Spring Boot 的 Web 三大核心交互案例详解 作为 Spring Boot 初学者,理解后端接口的编写和前端页面的交互至关重要。将通过三个经典的 Web 案例——**表单提交、AJAX 登录与状态管理、以及 JSON 数据交互**——带您掌握前后端联调的核心技巧和 Spring Boot 的关键注解。 案例一:表单提交与参数绑定(计算求和) 本案例展示最基础、最传统的 Web 交互方式:HTML 表单提交。 1.1 后端代码:CalcCo…
筑梦师 发布于 2026/4/6 更新于 2026/4/18 97K 浏览作为 Spring Boot 初学者,理解后端接口的编写和前端页面的交互至关重要。本文将通过三个经典的 Web 案例——表单提交、AJAX 登录与状态管理、以及 JSON 数据交互 ——带您掌握前后端联调的核心技巧和 Spring Boot 的关键注解。
1. 案例一:表单提交与参数绑定(计算求和) 本案例展示最基础、最传统的 Web 交互方式:HTML 表单提交。
1.1 后端代码:CalcController.java 使用 @RestController 简化接口编写,并通过方法参数接收表单数据。
package cn.overthinker.springboot;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/calc")
@RestController
public class CalcController {
@RequestMapping("/sum")
public String sum (Integer num1, Integer num2) {
if (num1 == null || num2 == null ) {
return "请求非法:请输入两个数字!" ;
}
return "计算结果为:" + (num1 + num2);
}
}
1.2 前端代码:calc.html
📋 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 >
<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 >
1.3 联调重点解析:参数绑定
前端 Form 的 name 属性 :前端 <input name="num1"> 中的 name 必须与后端方法的参数名 Integer num1完全一致 。
后端自动类型转换 :Spring Boot 会自动将 HTTP 请求中的字符串参数转换为 Java 方法所需的 Integer 类型。
2. 案例二:AJAX 异步交互与 Session 状态管理(用户登录) 本案例引入 AJAX 实现无刷新登录,并利用 Session 在服务器端保存用户状态。
2.1 后端代码:UserController.java 和 Person.java
UserController.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")
@RestController
public class UserController {
@PostMapping("/login")
public boolean login (String userName, String password, HttpSession session) {
if (!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
return false ;
}
if ("admin" .equals(userName) && "123456" .equals(password)) {
session.setAttribute("loginUser" , userName);
return true ;
}
return false ;
}
@GetMapping("/getLoginUser")
public String getLoginUser (HttpServletRequest request) {
HttpSession session = request.getSession(false );
if (session != null ) {
String loginUser = (String) session.getAttribute("loginUser" );
return loginUser;
}
return "" ;
}
}
Person.java (实体类)虽然未直接用于登录,但作为 JavaBean 演示参数绑定基础。
package cn.overthinker.springboot;
public class Person {
}
2.2 前端代码:login.html 和 index.html 使用 jQuery AJAX 进行异步登录,用户体验更好。
login.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 >
<script src ="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js" > </script >
<script >
function login ( ) {
$.ajax ({
url : "/user/login" ,
type : "post" ,
data : {
userName : $("#userName" ).val (),
password : $("#password" ).val ()
},
success : function (result ) {
if (result) {
location.href = "/index.html" ;
} else {
alert ("用户名或密码错误" );
}
}
});
}
</script >
</body >
</html >
index.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 ({
url : "user/getLoginUser" ,
type : "get" ,
success : function (userName ) {
$("#loginUser" ).text (userName || "(未登录)" );
}
});
</script >
</body >
</html >
2.3 联调重点解析:AJAX 与 Session
AJAX (Asynchronous JavaScript and XML) :允许前端在不刷新页面的情况下,与后端进行数据交换。在 login.html 中,我们使用 jQuery 的 $.ajax 实现异步请求。
Session 机制 :Session 是服务器端用来存储用户状态信息的机制。
当用户登录成功后,session.setAttribute("loginUser", userName); 在服务器上创建或关联一个 Session,并存入数据。
浏览器通过 Cookie 自动携带一个 Session ID 给服务器。
在 index.html 请求 /user/getLoginUser 时,服务器通过浏览器传来的 Session ID 找到对应的 Session,从而取出存储的 loginUser 信息,实现了状态保持。
3. 案例三:JSON 数据传输与 RESTful 接口(留言板) 本案例是现代 Web 开发最常用的方式:前后端通过 JSON 格式进行数据交互,后端使用 RESTful 风格 的接口。
3.1 后端代码:MessageController.java 和 MessageInfo.java
MessageController.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")
@RestController
public class MessageController {
private List<MessageInfo> messageInfoList = new ArrayList <>();
@PostMapping("/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 ;
}
@GetMapping("/getList")
public List<MessageInfo> getList () {
return messageInfoList;
}
}
MessageInfo.java (数据传输对象 DTO)使用 Lombok 的 @Data 注解自动生成 Getter/Setter。
package cn.overthinker.springboot;
import lombok.Data;
@Data
public class MessageInfo {
private String from;
private String to;
private String message;
}
3.2 前端代码:message.html
📋 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 ();
for (let msg of messages) {
let divE = "<div>" + msg.from + " 对 " + msg.to + " 说:" + msg.message + "</div>" ;
$(".message-list" ).append (divE);
}
}
});
}
loadMessages ();
function submit ( ) {
var from = $('#from' ).val ();
var to = $('#to' ).val ();
var say = $('#say' ).val ();
if (from == '' || to == '' || say == '' ) {
return ;
}
$. ({
: ,
: ,
: ,
: . ({
: ,
: to,
: say
}),
: ( ) {
(result) {
();
$( ). ( );
$( ). ( );
$( ). ( );
} {
( );
}
}
});
}
</script >
</body >
</html >
3.3 联调重点解析:@RequestBody 与 JSON
@RequestBody :这是 Spring Boot 接收 JSON 数据的关键注解。它告诉 Spring MVC:请将 HTTP 请求体(Request Body)中的 JSON 字符串解析,并自动映射到方法参数 MessageInfo messageInfo 对象中。
前端 contentType: "application/json" :前端必须设置此头信息,告诉服务器发送的是 JSON 格式数据。
前端 JSON.stringify(...) :JavaScript 的内置方法,用于将一个 JS 对象(如 {from: 'A', to: 'B', message: 'Hello'})转换为后端能够识别的 JSON 字符串。
JSON 字段匹配 :前端 JSON 中的键(Key)必须与后端 DTO (MessageInfo) 中的属性名(Field Name)保持一致(例如:message 对应 private String message;)。
4. 总结:前后端联调模式对比 联调模式 案例 核心机制 后端注解/参数接收 优点 缺点 Form 表单提交 求和计算器 浏览器直接跳转/刷新页面 方法参数名匹配 简单、无需 JavaScript 用户体验差、无法精细控制 AJAX (Query String) 登录系统 (GET/POST) 异步通信(无刷新) 方法参数名匹配 用户体验好、可局部更新 仅适用于少量简单数据 AJAX (JSON) 留言板 异步通信(无刷新) @RequestBody 接收 DTO传输复杂结构数据、最常用 需要配置 Content-Type 和 JSON.stringify
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
ajax
type
"post"
url
"/Message/publish"
contentType
"application/json"
data
JSON
stringify
from
from
to
message
success
function
result
if
loadMessages
'#from'
val
""
'#to'
val
""
'#say'
val
""
else
alert
"添加留言失败,请检查输入"