Spring MVC RESTful 员工管理实战 ——踩坑全记录

也是好久没写博客了,主要是进期末周之后忙着复习,把这事忘了。这期间MySQL、Maven、spring基础也已经学的差不多了。这周在学springmvc,总结踩的一些坑,这周的踩坑主要是 版本不匹配框架规范 的问题。

一、踩坑篇

坑1:pom.xml 中重复的 <build> 标签

Maven POM 中 <build> 只能出现一次,两个 build 会导致第二个被忽略,插件失效。

xml 复制代码
<!-- 错误 ❌ -->
<build><finalName>xxx</finalName></build>
<build><plugins>...</plugins></build>

<!-- 正确 ✅ -->
<build>
    <finalName>xxx</finalName>
    <plugins>...</plugins>
</build>

接下来两个就都是版本问题,我看的课用的jdk跟我的jdk版本不一样,导致有些地方他能实现,我实现不了

坑2:Spring 5.2.2 + Java 17 → Unsupported class file major version 61

JDK 17 编译的 class 文件(major version 61),Spring 5.2.2 的 ASM 库只支持到 Java 13,启动直接炸。

bash 复制代码
解决:Spring 版本升级到 5.3.20,统一用 ${spring.version} 管理

坑3:Java 17 没有 javax.annotation.Resource

Java 9+ 移除了 Java EE 相关包,@Resource 找不到。

kotlin 复制代码
解决:手动添加依赖 javax.annotation-api:1.3.2

坑4:Servlet 2.3 DTD → EL 表达式被禁用

web.xmlweb-app_2_3.dtd 时,JSP 2.0 的 EL 表达式 ${} 默认禁用,页面直接输出 ${employee.id} 原文字符串。

复制代码
解决:升级为 Servlet 2.5 Schema,EL 默认开启

坑5:web.xml DTD 元素顺序报错

DTD 2.3 要求 <filter> 全部在前,<filter-mapping> 全部在后,交替排列会报错。

xml 复制代码
<!-- 错误 ❌:交替排列 -->
<filter>A</filter>
<filter-mapping>A</filter-mapping>
<filter>B</filter>
<filter-mapping>B</filter-mapping>

<!-- 正确 ✅:先放完所有 filter,再放 mapping -->
<filter>A</filter>
<filter>B</filter>
<filter-mapping>A</filter-mapping>
<filter-mapping>B</filter-mapping>

坑6:路径变量和 @RequestMapping 不匹配

这个路径变量要注意下,我就是因为没注意,跳转的时候直接报错

java 复制代码
// 表单提交 /employee/1001
@RequestMapping("employee")   // ❌ 不匹配

@RequestMapping("employee/{id}")  // ✅ 匹配

坑7:浏览器 DELETE/PUT 请求 → 404

浏览器的 <form> 只支持 GET 和 POST,用 HiddenHttpMethodFilter 实现 "伪装":

html 复制代码
<form method="post">
    <input type="hidden" name="_method" value="DELETE">
</form>

Filter 拿到 _method 参数后,用装饰器模式重写 request.getMethod(),DispatcherServlet 拿到的就是 DELETE/PUT。


二、核心设计

接下来就是我觉得比较重要的几个点

RESTful 风格 URL 设计

URL 方法 作用
/employee GET 查询所有员工
/employee POST 新增员工
/employee PUT 更新员工(ID在隐藏字段)
/employee/{id} GET 回显单个员工
/employee/{id} DELETE 删除员工

同一个 URL,用 HTTP 方法区分操作。


关键注解

注解 用途
@Controller 声明为控制器
@RequestMapping(value, method) 映射请求
@PathVariable 取 URL 路径变量
@Resource 按名称注入 Bean(Java 标准)

数据容器 Model

java 复制代码
model.addAttribute("key", data);
// 底层等价于 → request.setAttribute("key", data);

三、完整请求链路(以删除为例)

sql 复制代码
点击[删除]按钮
  → POST /employee/1001 + _method=DELETE
  → HiddenHttpMethodFilter 拦截,转化为 DELETE
  → DispatcherServlet 匹配到 @RequestMapping("employee/{id}", DELETE)
  → delete(1001) → employeeDao.delete(1001) → Map.remove(1001)
  → return "redirect:/employee"
  → 浏览器重新 GET /employee,列表刷新,被删员工消失

五、总结

这周的踩坑本质都是 版本不匹配理解框架约定 的问题:

  1. Java 版本和 Spring 版本要匹配
  2. Java 9+ 需要手动添加 javax 依赖
  3. web.xml 的版本决定了 EL 是否可用
  4. RESTful 通过 HiddenHttpMethodFilter 弥补浏览器限制
  5. URL 设计和 HTTP 方法配合使用
相关推荐
凤山老林2 分钟前
轻量级规则引擎落地:Spring Boot 集成 LiteFlow 实现动态业务编排与热更新
java·spring boot·后端·规则引擎·liteflow
IT_陈寒7 分钟前
Python装饰器把我坑惨了,原来这样用才不掉链子
前端·人工智能·后端
程序员爱钓鱼26 分钟前
Rust Associated Type关联类型详解:为Trait定义内部类型
前端·后端·rust
程序员爱钓鱼29 分钟前
Go 编程实战:匿名函数 Anonymous Function——没有名字的函数与灵活回调
后端·面试·go
卷无止境1 小时前
FastAPI 后台任务的边界,以及 Celery、Redis 与自建调度系统的选择
后端·python
卷无止境1 小时前
Linux + Docker + FastAPI 工程化实践指南
后端·python·fastapi
AI绘画哇哒哒10 小时前
【建议收藏!】35岁后端血泪忠告,这3类人别硬转Agent(过来人亲述)
java·人工智能·后端·ai·程序员·大模型·agent
唐青枫11 小时前
一个值多种形态:Zig union、Tagged Union 与内存布局实战
后端
卷无止境11 小时前
Windows 上丝滑开发 Python,并稳定构建 Docker 镜像
后端·python·docker
Nturmoils11 小时前
备份完不算完,先还原到临时库验一遍
后端