基于 Spring Boot 的 Web 三大核心交互案例精讲
(2025-2026 主流写法,实战级别)
在 Spring Boot Web 开发中,真正高频、决定项目质量的“核心交互”通常可以浓缩为下面三大类:
- 前后端分离的 RESTful JSON 接口(最常见、最核心)
- 表单提交 + 文件上传 + 后端校验(传统 + 现代混合场景)
- WebSocket / SSE 实时双向通信(聊天、通知、仪表盘、进度条等)
下面用三个完整、可运行的案例,把这三大交互的核心写法、常见陷阱、最佳实践一次性讲清楚。
案例一:前后端分离 RESTful JSON 接口(最主流)
场景:用户管理系统(增删改查 + 分页 + 条件查询)
核心技术点:
- @RestController
- @RequestBody / @PathVariable / @RequestParam
- PageHelper 或 Spring Data JPA 分页
- 统一响应结构(Result)
- 全局异常处理 + 参数校验
代码结构示例(简洁版)
// 统一响应结构(强烈推荐)
public class Result<T> {
private int code;
private String msg;
private T data;
// success / error 静态工厂方法...
}
// Controller
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
// 查询列表(分页 + 条件)
@GetMapping
public Result<PageInfo<UserVO>> list(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@ModelAttribute UserQuery query) {
return Result.success(userService.listUsers(query, pageNum, pageSize));
}
// 新增
@PostMapping
public Result<UserVO> create(@Valid @RequestBody UserCreateDTO dto) {
return Result.success(userService.create(dto));
}
// 修改(PUT 幂等)
@PutMapping("/{id}")
public Result<UserVO> update(@PathVariable Long id,
@Valid @RequestBody UserUpdateDTO dto) {
return Result.success(userService.update(id, dto));
}
// 删除(支持批量)
@DeleteMapping
public Result<Void> delete(@RequestBody List<Long> ids) {
userService.delete(ids);
return Result.success();
}
}
最佳实践(2026主流):
- 使用
@Valid + BindingResult或MethodArgumentNotValidException全局处理校验失败 - 统一异常处理类
@ControllerAdvice+@ExceptionHandler - 前端统一拦截 axios response interceptor 处理 code ≠ 200 的情况
- 接口文档用 springdoc-openapi(替代 swagger)
案例二:表单 + 文件上传 + 后端校验
场景:用户注册/编辑资料(带头像上传)
核心技术点:
- multipart/form-data
- @RequestPart / MultipartFile
- 文件大小/类型校验
- 存储策略(本地 / MinIO / 阿里OSS)
@PostMapping(value = "/profile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Result<UserVO> updateProfile(
@RequestPart("user") @Valid UserUpdateDTO dto,
@RequestPart(value = "avatar", required = false) MultipartFile avatarFile) {
// 文件校验
if (avatarFile != null && !avatarFile.isEmpty()) {
// 1. 大小限制(Spring Boot 默认 1MB,可配置)
if (avatarFile.getSize() > 5 * 1024 * 1024) {
throw new BusinessException("头像文件不能超过5MB");
}
// 2. 类型限制
String contentType = avatarFile.getContentType();
if (contentType == null || !contentType.startsWith("image/")) {
throw new BusinessException("只允许上传图片文件");
}
// 3. 存储(这里用本地示例,生产用 MinIO/OSS)
String fileName = UUID.randomUUID() + "_" + avatarFile.getOriginalFilename();
Path path = Paths.get("/uploads/avatars/" + fileName);
Files.createDirectories(path.getParent());
avatarFile.transferTo(path.toFile());
dto.setAvatarUrl("/uploads/avatars/" + fileName);
}
return Result.success(userService.updateProfile(dto));
}
配置文件推荐(application.yml)
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
案例三:WebSocket / SSE 实时推送(通知、进度、聊天)
场景:后台任务进度实时推送 + 系统通知
推荐两种方式对比(2026主流选择)
| 方式 | 双向通信 | 浏览器兼容性 | 实现复杂度 | 典型场景 | 推荐指数 |
|---|---|---|---|---|---|
| WebSocket | 是 | 极好 | 中等 | 聊天、协作编辑、实时游戏 | ★★★★★ |
| SSE | 否(单向) | 极好 | 低 | 进度条、通知、股票价格推送 | ★★★★☆ |
SSE 极简实现(推荐入门首选)
@GetMapping(value = "/progress/{taskId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> progress(@PathVariable String taskId) {
return Flux.interval(Duration.ofSeconds(1))
.map(seq -> {
int percent = taskProgressService.getProgress(taskId);
return ServerSentEvent.<String>builder()
.id(String.valueOf(seq))
.event("progress")
.data(percent + "%")
.build();
})
.takeWhile(e -> {
int p = Integer.parseInt(e.data().replace("%", ""));
return p < 100;
});
}
前端(推荐用 EventSource 而不是 fetch)
const source = new EventSource(`/api/progress/${taskId}`);
source.onmessage = event => {
const percent = event.data;
progressBar.value = percent;
if (percent === "100%") {
source.close();
}
};
source.onerror = () => {
console.error("SSE 连接失败");
source.close();
};
WebSocket 推荐使用库:
- 后端:Spring WebSocket + STOMP(最成熟)
- 前端:@stomp/stompjs + sockjs-client
三大交互总结对比(快速记忆)
| 交互类型 | Content-Type | 核心注解 | 主要挑战 | 推荐中间件/库 |
|---|---|---|---|---|
| REST JSON | application/json | @RestController, @RequestBody | 参数校验、统一异常、跨域 | springdoc-openapi, validation |
| 表单+文件上传 | multipart/form-data | @RequestPart, MultipartFile | 文件大小/类型/存储/防重 | MinIO/OSS, apache commons-fileupload |
| 实时推送 | text/event-stream 或 ws | @GetMapping(produces=…) 或 WebSocket | 连接管理、心跳、断线重连 | WebFlux + Flux 或 STOMP over WS |
一句话总结:
Spring Boot Web 开发的核心竞争力其实是“结构化响应 + 统一异常 + 校验前置 + 实时能力”这四点做扎实了,90%的交互场景都能优雅解决。
你现在项目里最常遇到的是哪一类交互的痛点?
(json接口规范混乱?文件上传失败率高?实时推送断连?跨域问题?参数校验重复代码多?)
告诉我具体场景,我可以直接给你更针对性的代码模板或最佳实践。