Request Method Not Supported (405) in Spring – 请求方法不支持(405),在Spring

最后修改: 2018年 10月 23日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’ll focus on a common error, ‘Request Method not Supported – 405′, that developers face while exposing their APIs for specific HTTP verbs with Spring MVC.

在这个快速教程中,我们将专注于一个常见的错误,即 “不支持请求方法–405″,这是开发人员在用Spring MVC为特定的HTTP动词暴露他们的API时所面临的问题。

Naturally, we’ll also discuss the common causes of this error.

当然,我们也会讨论造成这种错误的常见原因。

2. Request Method Basics

2.请求方法基础知识

If we’re just starting to learn about Spring MVC, here’s a good intro article we can start with.

如果我们刚刚开始学习Spring MVC,这里有一篇很好的介绍性文章,我们可以从这里开始学习。

We’ll also have a very quick look at the basics to understand the request methods supported by Spring, and some of the common classes of interest here.

我们还将快速浏览一下基础知识,了解Spring所支持的请求方法,以及这里的一些常用类。

In a highly simplified way, MVC HTTP methods are basic operations that a request can trigger on the server. For example, some methods fetch the data from the server, some submit data to the server, some might delete the data, etc.

以一种高度简化的方式,MVC HTTP方法是一个请求可以在服务器上触发的基本操作。例如,有些方法从服务器获取数据,有些向服务器提交数据,有些可能删除数据,等等。

The @RequestMapping annotation specifies the supported methods for the request.

@RequestMapping注解指定了请求的支持方法。

Spring declares all the supported request methods under an enum, RequestMethod, which specifies the standard GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, and TRACE verbs.

Spring在一个枚举下声明了所有支持的请求方法,RequestMethod,它指定了标准的GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE verbs。

The Spring DispatcherServlet supports all of them by default, except OPTIONS and TRACE. @RequestMapping uses the RequestMethod enum to specify which methods are supported.

Spring DispatcherServlet 默认支持所有这些方法,除了OPTIONSTRACE. @RequestMapping使用RequestMethod枚举来指定哪些方法被支持。

3. Simple MVC Scenario

3.简单的MVC场景

Now let’s have a look at a code example that maps all HTTP methods:

现在让我们看看一个映射所有HTTP方法的代码例子。

@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();
    }
}

Notice how the example declares the findEmployee() method. It doesn’t specify any specific request method, which means this URL supports all default methods.

注意这个例子是如何声明findEmployee()方法的。它没有指定任何具体的请求方法,这意味着这个URL支持所有的默认方法。

We can request the API using different supported methods, such as curl:

我们可以使用不同的支持方法来请求API,如curl。

$ 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"}]

Naturally, we can send the request in multiple ways: a simple curl command, Postman, AJAX, etc.

当然,我们可以用多种方式发送请求:一个简单的curl命令、Postman、AJAX等。

And, of course, we expect to get the 200 OK response if the request is correctly mapped and successful.

当然,如果请求被正确映射并成功,我们希望得到200 OK响应。

4. Problem Scenario – the HTTP 405

4.问题情景–HTTP 405

But what we’re discussing here is the scenarios where the request isn’t successful.

但我们在这里讨论的是请求不成功的情况。

405 Method Not Allowed’ is one of the most common errors we observe while working with Spring requests.

405 Method Not Allowed“是我们在处理Spring请求时观察到的最常见错误之一。

Let’s have a look at what happens if we specifically define and handle GET requests in Spring MVC:

让我们看看如果我们在Spring MVC中专门定义和处理GET请求会发生什么。

@RequestMapping(
  value = "/employees", 
  produces = "application/json", 
  method = RequestMethod.GET)
public List<Employee> findEmployees() {
    ...
}

// send the PUT request using CURL
$ 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"}

5. 405 Not Support – Reason, Solution

5.405不支持 – 原因,解决方案

What we’re getting in the previous scenario is an HTTP response with the 405 Status Code, which is a client error indicating that the server doesn’t support the method/verb sent in the request.

在前面的情况下,我们得到的是一个带有405状态代码的HTTP响应,这是一个客户端错误,表明服务器不支持请求中发送的方法/动词。

As the name here suggests, the reason for this error is sending the request with a non-supported method.

正如这里的名字所示,这个错误的原因是用一个不支持的方法发送请求。

As we can expect, we can solve this by defining an explicit mapping for PUT in the existing method mapping:

正如我们所期望的,我们可以通过在现有的方法映射中为PUT定义一个明确的映射来解决这个问题。

@RequestMapping(
  value = "/employees", 
  produces = "application/json", 
  method = {RequestMethod.GET, RequestMethod.PUT}) ...

Alternatively, we can define the new method/mapping separately:

另外,我们也可以单独定义新的方法/映射。

@RequestMapping(value = "/employees", 
  produces = "application/json", 
  method=RequestMethod.PUT)
public List<Employee> postEmployees() ...

6. Conclusion

6.结语

The request method/verb is a critical aspect in HTTP communication. We need to be careful with the exact semantics of the operations we define on the server side, and the exact requests we send in.

请求方法/动词是HTTP通信中的一个关键环节。我们需要谨慎对待我们在服务器端定义的操作的确切语义,以及我们发送的确切请求。

As always, the examples shown in this article are available on over on GitHub.

一如既往,本文所展示的例子可在GitHub上找到。