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

基于 Spring Boot 的 Web 三大核心交互案例精讲
(2025-2026 主流写法,实战级别)

在 Spring Boot Web 开发中,真正高频、决定项目质量的“核心交互”通常可以浓缩为下面三大类:

  1. 前后端分离的 RESTful JSON 接口(最常见、最核心)
  2. 表单提交 + 文件上传 + 后端校验(传统 + 现代混合场景)
  3. 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 + BindingResultMethodArgumentNotValidException 全局处理校验失败
  • 统一异常处理类 @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 JSONapplication/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接口规范混乱?文件上传失败率高?实时推送断连?跨域问题?参数校验重复代码多?)

告诉我具体场景,我可以直接给你更针对性的代码模板或最佳实践。

文章已创建 4791

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部