基于 Spring Boot 的 Web 三大核心交互案例精讲

基于 Spring Boot 的 Web 三大核心交互案例精讲
—知识点专栏——JavaEE专栏—


作为 Spring Boot 初学者,理解后端接口的编写和前端页面的交互至关重要。本文将通过三个经典的 Web 案例——表单提交、AJAX 登录与状态管理、以及 JSON 数据交互——带您掌握前后端联调的核心技巧和 Spring Boot 的关键注解。

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

本案例展示最基础、最传统的 Web 交互方式:HTML 表单提交。

1.1 后端代码:CalcController.java

使用 @RestController 简化接口编写,并通过方法参数接收表单数据。

packagecn.overthinker.springboot;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;@RequestMapping("/calc")@RestControllerpublicclassCalcController{/** * 求和接口:通过方法参数名自动接收前端表单提交的 num1 和 num2 */@RequestMapping("/sum")publicStringsum(Integer num1,Integer num2){// 使用 Integer 包装类进行非空判断,避免空指针异常if(num1 ==null|| num2 ==null){return"请求非法:请输入两个数字!";}// 计算并返回结果return"计算结果为:"+(num1 + num2);}}

1.2 前端代码:calc.html

在这里插入图片描述


在这里插入图片描述
📋 HTML 代码
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="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><divclass="calculator-container"><h1>简单求和计算器</h1><formaction="/calc/sum"method="post"> 数字1:<inputname="num1"type="text"placeholder="请输入数字1"><br> 数字2:<inputname="num2"type="text"placeholder="请输入数字2"><br><inputtype="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.javaPerson.java

UserController.java (核心逻辑)
packagecn.overthinker.springboot;importjakarta.servlet.http.HttpServletRequest;importjakarta.servlet.http.HttpSession;importorg.springframework.util.StringUtils;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;@RequestMapping("/user")@RestControllerpublicclassUserController{/** * 登录接口:使用 HttpSession 存储用户信息 */@PostMapping("/login")publicbooleanlogin(String userName,String password,HttpSession session){if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){returnfalse;}// 硬编码校验(实际项目应查询数据库)if("admin".equals(userName)&&"123456".equals(password)){// **核心知识点:登录成功后,将用户名存入 Session** session.setAttribute("loginUser", userName);returntrue;}returnfalse;}/** * 获取当前登录用户接口:从 Session 中读取用户信息 */@GetMapping("/getLoginUser")publicStringgetLoginUser(HttpServletRequest request){// request.getSession(false):如果 Session 不存在,则不创建HttpSession session = request.getSession(false);if(session !=null){String loginUser =(String) session.getAttribute("loginUser");return loginUser;}return"";}}
Person.java (实体类)

虽然未直接用于登录,但作为 JavaBean 演示参数绑定基础。

packagecn.overthinker.springboot;// 略:包含 name, password, age 属性及其 Getter/Setter 和 toString 方法publicclassPerson{// ... 属性、Getter/Setter、toString ...}

2.2 前端代码:login.htmlindex.html

在这里插入图片描述


在这里插入图片描述

使用 jQuery AJAX 进行异步登录,用户体验更好。

login.html (登录页面)
<!DOCTYPEhtml><htmllang="en"><head><metacharset="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><divclass="login-box"><h1>用户登录</h1> 用户名:<inputname="userName"type="text"id="userName"placeholder="请输入用户名"><br> 密码:<inputname="password"type="password"id="password"placeholder="请输入密码"><br><inputtype="button"value="登录"onclick="login()"></div><scriptsrc="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script><script>functionlogin(){ $.ajax({ url:"/user/login", type:"post",// 核心联调:通过 AJAX 传递参数 data:{ userName:$("#userName").val(), password:$("#password").val()},success:function(result){if(result){// 登录成功,跳转到首页 location.href ="/index.html";}else{alert("用户名或密码错误");}}});}</script></body></html>
index.html (首页 - 获取登录信息)
<!doctypehtml><htmllang="en"><head><metacharset="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><divclass="welcome">欢迎回来,登录人: <spanid="loginUser"></span></div><scriptsrc="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script><script>// 页面加载后立即发起 AJAX 请求获取 Session 中的登录信息 $.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.javaMesseageInfo.java

MessageController.java (核心逻辑)
packagecn.overthinker.springboot;importorg.springframework.util.StringUtils;importorg.springframework.web.bind.annotation.*;importjava.util.ArrayList;importjava.util.List;@RequestMapping("/Message")@RestControllerpublicclassMessageController{// 存储留言的列表(模拟数据库存储)privateList<MesseageInfo> messeageInfoList =newArrayList<>();/** * 发布留言接口:使用 @RequestBody 接收 JSON 数据 */@PostMapping("/publish")publicBooleanpublish(@RequestBodyMesseageInfo messeageInfo){// 参数校验if(!StringUtils.hasLength(messeageInfo.getFrom())||!StringUtils.hasLength(messeageInfo.getTo())||!StringUtils.hasLength(messeageInfo.getMessage())){returnfalse;} messeageInfoList.add(messeageInfo);returntrue;}/** * 获取留言列表接口:返回 JSON 数组 */@GetMapping("/getList")publicList<MesseageInfo>getList(){return messeageInfoList;}}
MesseageInfo.java (数据传输对象 DTO)

使用 Lombok 的 @Data 注解自动生成 Getter/Setter。

packagecn.overthinker.springboot;importlombok.Data;@Data// Lombok 注解,自动生成 Getter/Setter, toString, equals等方法publicclassMesseageInfo{privateString from;privateStringto;privateString message;// 注意:前端传的字段名是 message}

3.2 前端代码:message.html

在这里插入图片描述

前端使用 AJAX 发送 JSON 格式的数据。

📋 HTML 代码
<!DOCTYPEhtml><htmllang="en"><head><metacharset="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><divclass="container"><h1>留言板</h1><pclass="grey">输入后点击提交,信息将显示在下方</p><divclass="row"><span>谁:</span><inputtype="text"id="from"placeholder="你的名字"></div><divclass="row"><span>对谁:</span><inputtype="text"id="to"placeholder="你想对谁说"></div><divclass="row"><span>说什么:</span><inputtype="text"id="say"placeholder="你的留言内容"></div><inputtype="button"value="提交留言"id="submit"onclick="submit()"><divclass="message-list"></div></div><scriptsrc="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script><script>// 页面加载时自动获取并展示所有留言functionloadMessages(){ $.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();functionsubmit(){varfrom=$('#from').val();var to =$('#to').val();var say =$('#say').val();if(from==''|| to ==''|| say ==''){return;}// 核心联调:发送 JSON 数据 $.ajax({ type:"post", url:"/Message/publish",// 1. 设置 Content-Type 为 application/json contentType:"application/json",// 2. 使用 JSON.stringify 将 JS 对象转换为 JSON 字符串 data:JSON.stringify({from:from, to: to,// 注意:前端字段名为 message,与后端 DTO 匹配 message: say }),success:function(result){if(result){// 提交成功后重新加载列表loadMessages();// 清空输入框$('#from').val("");$('#to').val("");$('#say').val("");}else{alert("添加留言失败,请检查输入");}}});}</script></body></html>

3.3 联调重点解析:@RequestBody 与 JSON

  • @RequestBody:这是 Spring Boot 接收 JSON 数据的关键注解。它告诉 Spring MVC:请将 HTTP 请求体(Request Body)中的 JSON 字符串解析,并自动映射到方法参数 MesseageInfo messeageInfo 对象中。
  • 前端 contentType: "application/json":前端必须设置此头信息,告诉服务器发送的是 JSON 格式数据。
  • 前端 JSON.stringify(...):JavaScript 的内置方法,用于将一个 JS 对象(如 {from: 'A', to: 'B', message: 'Hello'})转换为后端能够识别的 JSON 字符串。
  • JSON 字段匹配:前端 JSON 中的键(Key)必须与后端 DTO (MesseageInfo) 中的属性名(Field Name)保持一致(例如:message 对应 private String message;)。

4. 总结:前后端联调模式对比

联调模式案例核心机制后端注解/参数接收优点缺点
Form 表单提交求和计算器浏览器直接跳转/刷新页面方法参数名匹配简单、无需 JavaScript用户体验差、无法精细控制
AJAX (Query String)登录系统 (GET/POST)异步通信(无刷新)方法参数名匹配用户体验好、可局部更新仅适用于少量简单数据
AJAX (JSON)留言板异步通信(无刷新)@RequestBody 接收 DTO传输复杂结构数据、最常用需要配置 Content-TypeJSON.stringify

若你在学习过程中遇到其他问题,或有好的学习经验分享,欢迎在评论区留言!一起交流进步🌟

在这里插入图片描述

Read more

【MySQL数据库基础】(六)MySQL 表的约束详解:从基础到实战,拿捏数据合法性!

【MySQL数据库基础】(六)MySQL 表的约束详解:从基础到实战,拿捏数据合法性!

前言         在 MySQL 数据库开发中,我们总希望存入表中的数据是合法、规范、符合业务逻辑的。虽然数据类型能对字段做基础限制,但面对复杂的业务需求,仅靠数据类型远远不够。比如要求邮箱唯一、用户名不能为空、学生的班级必须是已存在的班级…… 这些需求都需要靠表的约束来实现。         表的约束是数据库保证数据完整性的核心手段,它能从业务逻辑层面过滤无效数据,避免脏数据进入数据库。今天这篇文章就带大家全面吃透 MySQL 中最常用的表约束,包括null/not null、default、comment、zerofill、primary key、auto_increment、unique key、foreign key,从基础概念到实操案例,手把手教你用约束拿捏数据合法性!下面就让我们正式开始吧! 一、为什么需要表的约束?         先看一个简单的例子:如果我们创建一个班级表,只定义字段和数据类型,不添加任何约束,会发生什么? -- 无约束的班级表 create table myclass( class_

By Ne0inhk
ctfshowweb入门 SSTI模板注入专题保姆级教程(一)

ctfshowweb入门 SSTI模板注入专题保姆级教程(一)

前言:本来这篇是不打算写的,自己稍微记录一下就行了,但是我发现后面的题难度也挺大的,而且好多更细的不记录后面也容易忘记,并且网上很多师傅讲的直接是payload(我还是太菜了看不懂),有很多都是我没见到过的,因此这里综合记录一下(其实最重要的是在这里写的能保存成pdf)同时也是对自己找的资料进行一个汇总 web361 这里我之前详细讲过了就不再赘述,ctfshowweb361--一道题从0入门SSTI模板注入,这里面也是直接从0基础讲起,如果还是有不懂的网上再找点资料看看【我最后也放了参考】,后续题目都是在这基础上进行的,熟悉了361的方法之后才能继续做后面题目。 web362 按照之前的方法进行尝试,发现过滤了除1和7以外的数字,而我们要找的是132,因此这里可以采用全角符号绕过【具体怎么开问下AI就行,因为我用的是Windows自带的,在设置里面进行设置,然后可能有的人用了其他输入法之类的,所以这里就不上图了】 实在找不到的话我直接打在下面: 1234567890 (全角 可以对比半角:1234567890) 然后就是输入我们的payload: ?name={{

By Ne0inhk
Java Web 网上商城系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

Java Web 网上商城系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着电子商务的快速发展,网上商城系统已成为现代商业活动的重要组成部分。传统的单体架构系统在应对高并发、分布式部署及快速迭代需求时面临诸多挑战,亟需采用更高效、灵活的技术架构进行升级。本论文基于实际需求,设计并实现了一个基于前后端分离架构的Java Web网上商城系统,旨在解决传统系统性能瓶颈、维护成本高等问题。系统采用SpringBoot2、Vue3、MyBatis-Plus和MySQL8.0等技术栈,具备良好的扩展性和可维护性,能够满足中小型电商平台的业务需求。关键词:网上商城、SpringBoot2、Vue3、MyBatis-Plus、MySQL8.0。 本系统采用前后端分离架构,后端基于SpringBoot2框架实现RESTful API,提供高效的数据交互能力;前端使用Vue3框架构建响应式用户界面,提升用户体验;数据库采用MySQL8.0存储业务数据,结合MyBatis-Plus简化数据操作逻辑。系统功能模块包括用户管理、商品管理、订单管理、购物车管理及支付集成等,支持多角色权限控制、商品分类检索、订单状态追踪等功能。通过分布式缓存和异步消息队列优化系统性能,确保高

By Ne0inhk

ComfyUI vs WebUI对比实测:云端GPU 1小时低成本体验

ComfyUI vs WebUI对比实测:云端GPU 1小时低成本体验 对于资深AI图像生成用户来说,选择合适的工具直接关系到生产效率和创作质量。当需要评估ComfyUI工作流与传统WebUI在运行Qwen-Image-2512时的性能差异时,一个独立、可快速启停的临时环境显得尤为重要。本文将带你通过云端GPU资源,在1小时内完成对两种主流界面的全面对比测试,帮助你做出最适合自身生产流程的技术选型。 本次实测聚焦于Qwen-Image-2512这一先进模型——它在人物真实感、自然细节和文本渲染方面均有显著提升,甚至在盲测中超越部分闭源商业模型。我们将从部署效率、操作逻辑、生成质量、资源占用等多个维度进行深度剖析,确保你能获得客观、实用的决策依据。无论你是希望优化现有工作流的专业设计师,还是想探索更高效创作方式的技术爱好者,这篇文章都能为你提供清晰的指引。 1. 环境准备:为什么选择云端GPU进行对比测试 1.1 资深用户的典型困境与解决方案 作为一名资深AI创作者,你可能经常面临这样的挑战:现有的本地设备已经满载运行着多个重要任务,无论是训练模型、渲染视频还是处理大量数据,

By Ne0inhk