The HttpMediaTypeNotAcceptableException in Spring MVC – Spring MVC中的HttpMediaTypeNotAcceptableException

最后修改: 2017年 6月 27日

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

1. Overview

1.概述

In this quick article, we’ll have a look at the HttpMediaTypeNotAcceptableException exception, and understand the cases where we might encounter it.

在这篇快速文章中,我们将看看HttpMediaTypeNotAcceptableException异常,并了解我们可能遇到的情况。

2. The Problem

2.问题

When implementing an API endpoint with Spring, we generally need to specify the consumed/produced media types (via the consumes and produces parameters). This narrows down the possible formats that the API will return back to the client for that specific operation.

在用Spring实现API端点时,我们通常需要指定消费/生产的媒体类型(通过consumesproduces参数)。这就缩小了API为该特定操作返回给客户端的可能格式。

HTTP also has the dedicated “Accept” header – which is used to specify media types the client recognizes and can accept. Simply put, the server will send back a resource representation using one of the media types the client requested.

HTTP也有专门的“Accept”头–用于指定客户端识别和可以接受的媒体类型。简单地说,服务器将使用客户要求的媒体类型之一发回一个资源表示。

However, if there is no common type that both sides can work with, Spring will throw the HttpMediaTypeNotAcceptableException exception.

然而,如果没有双方都能使用的共同类型,Spring将抛出HttpMediaTypeNotAcceptableException异常。

3. Practical Example

3.实际案例

Let’s create a simple example that will demonstrate this scenario.

让我们创建一个简单的例子,来证明这种情况。

We’re going to use a POST endpoint – which can only work with “application/json and returns JSON data back as well:

我们将使用一个POST端点–它只能与“application/json一起工作,并且也会返回JSON数据。

@PostMapping(
  value = "/test", 
  consumes = MediaType.APPLICATION_JSON_VALUE, 
  produces = MediaType.APPLICATION_JSON_VALUE)
public Map<String, String> example() {
    return Collections.singletonMap("key", "value");
}

Then, let’s send a request using CURL with a non-recognized content type:

然后,让我们用CURL发送一个内容类型不被识别的请求。

curl -X POST --header "Accept: application/pdf" http://localhost:8080/test -v

> POST /test HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.51.0
> Accept: application/pdf

The response we got is:

我们得到的答复是。

< HTTP/1.1 406 
< Content-Length: 0

4. The Solution

4.解决方案

There’s only one way to resolve the issue – to send/receive one of the supported types.

要解决这个问题,只有一个办法–发送/接收一个支持的类型。

All we can do is to provide a more descriptive message (by default Spring returns an empty body) with a custom ExceptionHandler notifying a client about all acceptable media types.

我们能做的就是提供一个更具描述性的消息(默认情况下,Spring返回一个空的主体),用一个自定义的ExceptionHandler通知客户所有可接受的媒体类型。

In our case, it’s only “application/json”:

在我们的例子中,它只是“application/json”

@ResponseBody
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public String handleHttpMediaTypeNotAcceptableException() {
    return "acceptable MIME type:" + MediaType.APPLICATION_JSON_VALUE;
}

5. Conclusion

5.结论

In this tutorial, we’ve considered the HttpMediaTypeNotAcceptableException exception thrown by Spring MVC when there’s a mismatch between what the client asks for and what the server can actually produce.

在本教程中,我们考虑了Spring MVC抛出的HttpMediaTypeNotAcceptableException异常,即客户端要求的内容与服务器实际能产生的内容不匹配。

As always, the code snippets mentioned in the article can be found in our GitHub repository.

一如既往,文章中提到的代码片段可以在我们的GitHub资源库中找到。