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.xml 用 web-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 方法配合使用
相关推荐
To_OC8 小时前
从一头雾水到跑通全流程:我用一个周末啃透了JWT登录鉴权
前端·后端·http
前端兰博9 小时前
05-Redis
redis·后端
databook10 小时前
从手动检查到自动监控:一个数据质量工作流的实现
后端·python·数据分析
【JAVA】玩家10 小时前
Spring核心原理全解析:从零到生产实战
java·后端·spring
东风破_10 小时前
从 Neo4j 到 GraphRAG:用 Text-to-Cypher 构建图检索 RAG
人工智能·后端
llqbzllll12 小时前
Spring AI 工具调用不是反射一下就结束:用 2.0.1 跑通失败恢复与调用上限
人工智能·后端
狼爷12 小时前
Rust/Go/Java/Python/PHP 大比拼:负载下后端框架到底差多少?
java·后端·编程语言
mantou13213 小时前
我给 AI Agent 做了个「油猴」:让 Claude Code / Codex 直接用你已登录的浏览器
前端·javascript·后端
程序员老赵13 小时前
Docker 部署 DeepSeek Harness:轻松搭建局域网里的 AI Agent 平台
后端·ai编程·deepseek
YIAN13 小时前
实战|用 DeepSeek + SQLite 从零搭建轻量 Text2SQL 查询助手
后端·sqlite·deepseek