1. 概述
在使用 Spring MVC 开发 Web 接口时,我们经常会遇到一个常见的错误:405 Method Not Allowed。这个错误通常发生在客户端向服务端发送了一个不被支持的 HTTP 方法请求。
本文将带你快速了解这个错误的成因,并提供几种常见的解决方案。
2. 请求方法基础
如果你刚接触 Spring MVC,可以先看看这篇入门指南。
Spring MVC 支持标准的 HTTP 请求方法,这些方法定义在 RequestMethod
枚举中:
GET
HEAD
POST
PUT
PATCH
DELETE
OPTIONS
TRACE
其中,Spring 的 DispatcherServlet
默认支持除 OPTIONS
和 TRACE
外的所有方法。
我们可以通过 @RequestMapping
注解来指定某个接口支持的请求方法。如果不显式指定,默认会支持所有方法。
3. 简单的 MVC 场景
下面是一个简单的 Controller 示例,它没有指定任何请求方法,因此默认支持所有方法:
@RestController
@RequestMapping(value="/api")
public class RequestMethodController {
@Autowired
private EmployeeService service;
@RequestMapping(value = "/employees", produces = "application/json")
public List<Employee> findEmployees()
throws InvalidRequestException {
return service.getEmployeeList();
}
}
此时,你可以使用任何支持的方法(如 GET、POST)访问 /api/employees
接口:
$ curl --request POST http://localhost:8080/api/employees
[{"id":100,"name":"Steve Martin","contactNumber":"333-777-999"},
{"id":200,"name":"Adam Schawn","contactNumber":"444-111-777"}]
只要请求路径和处理逻辑匹配,就能正常返回 200 OK。
4. 问题场景:HTTP 405 错误
现在我们来看一个出问题的场景。假设我们只允许 GET 请求访问某个接口:
@RequestMapping(
value = "/employees",
produces = "application/json",
method = RequestMethod.GET)
public List<Employee> findEmployees() {
...
}
然后我们尝试用 PUT 方法请求该接口:
$ curl --request PUT http://localhost:8080/api/employees
{
"timestamp":1539720588712,
"status":405,
"error":"Method Not Allowed",
"exception":"org.springframework.web.HttpRequestMethodNotSupportedException",
"message":"Request method 'PUT' not supported",
"path":"/api/employees"
}
✅ 结果就是 405 错误,Spring 明确告诉你:不支持你用 PUT 方法访问这个接口!
5. 405 错误的原因与解决方案
❌ 原因总结
HTTP 405 错误本质上是一个客户端错误,表示你发送的 HTTP 方法(GET、POST、PUT 等)不被服务端支持。
✅ 解决方案
方案一:扩展支持的方法
你可以在 @RequestMapping
中添加多个方法支持:
@RequestMapping(
value = "/employees",
produces = "application/json",
method = {RequestMethod.GET, RequestMethod.PUT})
public List<Employee> findEmployees() {
...
}
方案二:为不同方法定义不同的处理方法
你也可以为每个方法单独定义处理逻辑:
@RequestMapping(value = "/employees",
produces = "application/json",
method = RequestMethod.GET)
public List<Employee> getEmployees() {
...
}
@RequestMapping(value = "/employees",
produces = "application/json",
method = RequestMethod.PUT)
public List<Employee> updateEmployees() {
...
}
⚠️ 注意:如果你的 API 需要严格的 RESTful 设计,建议为不同语义的操作定义不同的方法,而不是一股脑支持所有方法。
6. 小结
HTTP 请求方法是 Web 通信中的核心部分,Spring MVC 提供了灵活的方式来控制接口支持的方法类型。
当你遇到 405 错误时,不要慌,先检查你发送的请求方法是否被接口支持。很多时候只是因为忘了加 method
参数或者方法写错了。
示例代码可以在 GitHub 仓库 中找到。