也是好久没写博客了,主要是进期末周之后忙着复习,把这事忘了。这期间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,列表刷新,被删员工消失
五、总结
这周的踩坑本质都是 版本不匹配 和 理解框架约定 的问题:
- Java 版本和 Spring 版本要匹配
- Java 9+ 需要手动添加 javax 依赖
- web.xml 的版本决定了 EL 是否可用
- RESTful 通过
HiddenHttpMethodFilter弥补浏览器限制 - URL 设计和 HTTP 方法配合使用