SpringMVC中的Restful风格
一、核心思想:把一切都看作“资源”
RESTful 风格的核心思想非常直观:将一个服务器提供的内容看作一个个“资源”(Resource)。
比如,一个博客系统有:
-
用户(Users)
-
文章(Articles)
-
评论(Comments)
RESTful API 的设计,就是围绕这些“资源”进行一系列的“操作”。这些操作对应于我们常用的 HTTP 协议方法。
二、核心原则与特征
RESTful 架构通常遵循以下几个关键原则:
-
以资源为中心
每个 URI(统一资源标识符)都唯一对应一个资源。URI 应该使用名词(表示资源),而不是动词(表示操作)。
-
好:
/articles(文章集合),/articles/123(ID 为 123 的特定文章) -
不好:
/getAllArticles,/createNewArticle
-
-
统一接口
使用标准的 HTTP 方法来定义对资源的操作,这是 RESTful 最显著的特征。
-
GET:获取/查询资源。安全且幂等的(多次请求效果相同)。
-
POST:创建新资源。
-
PUT:更新/替换整个资源。幂等的(多次更新结果一致)。
-
PATCH:部分更新资源。
-
DELETE:删除资源。幂等的。
-
-
无状态
服务器不会保存客户端的任何会话状态。每一次从客户端发来的请求都必须包含处理该请求所需的所有信息(如认证令牌、参数等)。这简化了服务器设计,提高了可伸缩性。
-
可缓存
服务器端的响应应该明确表明本响应是否可以被缓存,以减少客户端重复请求的次数,提升性能。
-
分层系统
客户端不需要知道它是直接连接至最终服务器,还是通过中间层(如负载均衡器、代理服务器)连接的。这提高了系统的可扩展性和安全性。
三、实战示例:一个博客文章的 API 设计
假设我们要管理“文章”资源,一个符合 RESTful 风格的 API 设计如下:
|
操作 |
HTTP 方法 |
URL |
描述 |
返回 HTTP 状态码(常见) |
|---|---|---|---|---|
|
获取所有文章 |
GET |
|
获取文章列表 |
200 OK(成功) |
|
获取单篇文章 |
GET |
|
获取 ID 为 123 的文章 |
200 OK(成功) |
|
创建新文章 |
POST |
|
创建一篇新文章 |
201 Created(创建成功) |
|
更新整篇文章 |
PUT |
|
替换 ID 为 123 的整篇文章 |
200 OK(成功) |
|
部分更新文章 |
PATCH |
|
只更新 ID 为 123 的文章的标题 |
200 OK(成功) |
|
删除一篇文章 |
DELETE |
|
删除 ID 为 123 的文章 |
204 No Content(删除成功,无返回体) |
@RequestMapping(path = "emp",method = RequestMethod.POST)
public void save(){
System.out.println("xsy保存了员工");
}
/**
* get请求 一般用于查询
*/
@RequestMapping(path = "/emp",method = RequestMethod.GET)
public void findAll(){
System.out.println("xsy查询所有员工");
}
/**
* get 请求一般用于查询
* @param id
*/
@RequestMapping(path = "/emp/{id}",method = RequestMethod.GET)
public void findget1(@PathVariable("id") int id){
System.out.println("xsy查询了员工"+id+"员工");
}
/**
* put 请求一般用于更新
* @param id
*/
@RequestMapping(path = "/emp/{id}",method = RequestMethod.PUT)
public void findput(@PathVariable("id") int id){
System.out.println("xsy修改了员工"+id+"员工");
}
/**
* delete 一般用于删除
* @param id
*/
@RequestMapping(path = "/emp/{id}",method = RequestMethod.DELETE)
public void finddelete(@PathVariable("id") int id){
System.out.println("xsy删除了员工"+id+"员工");
}
/**
* patch 一般用于更新部分资源
* @param id
*/
@RequestMapping(path = "/emp/{id}",method = RequestMethod.PATCH)
public void findpatch(@PathVariable("id") int id){
System.out.println("xsy更新部分信息了员工"+id+"员工");
}
Spring MVC 中 PUT 与 GET 请求的差异总结
1. 设计理念差异
-
GET 请求:遵循传统 MVC 模式,主要用于数据查询和页面导航,天然支持页面跳转和视图渲染
-
PUT 请求:遵循 RESTful 风格,主要用于资源更新,默认期望返回操作结果(数据)而非页面
PUT请求在Spring MVC中默认被当作RESTful API请求处理,期望返回数据而非页面跳转。而GET请求默认支持传统的MVC页面跳转模式。
Tomcat 对 JSP 的HTTP方法限制
默认支持的HTTP方法
-
✅ GET
-
✅ POST
-
✅ HEAD
-
❌ PUT
-
❌ DELETE
-
❌ PATCH
@PutMapping("/user")
public String update() {
return "success"; // 试图跳转到 success.jsp
}
// 实际执行流程:
// 1. 控制器方法执行完毕
// 2. Spring MVC 尝试转发到 /success.jsp
// 3. Tomcat 拒绝:JSP页面不支持PUT方法访问
// 4. 抛出HTTP 405错误:JSPs only permit GET, POST or HEAD
Tomcat服务器默认配置中,JSP页面只允许GET、POST、HEAD方法,不允许PUT、DELETE等其他HTTP方法。当你返回"suc"视图时,Spring MVC会尝试转发到suc.jsp,但Tomcat拒绝了这次转发。
表单发送PUT请求
在JSP中,表单本身不能直接发送PUT请求,但可以通过一些技巧实现。以下是详细解决方案:
问题分析
HTML表单原生只支持两种方法:
-
method="get"→ GET请求 -
method="post"→ POST请求
不支持 PUT、DELETE等其他HTTP方法。
解决方案
使用隐藏域 + 过滤器
1. 配置HiddenHttpMethodFilter
在web.xml中添加过滤器:
<!-- 在characterEncodingFilter之后添加 -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2. JSP表单中使用隐藏域
<form action="http://localhost:8080/emp/1" method="post">
<!-- 隐藏域指定实际方法 -->
<input type="hidden" name="_method" value="put"/>
<button type="submit">更新部门</button>
</form>

9350

被折叠的 条评论
为什么被折叠?



