1. 概述
在本文檔中,我們將探討 HttpMediaTypeNotAcceptableException 異常,並瞭解可能遇到的情況。
2. 問題描述
在 Spring 中實現 API 端點時,我們通常需要指定消耗/產生的媒體類型(通過 consumes 和 produces 參數)。這會縮小 API 返回給客户端的特定操作可能使用的格式範圍。
HTTP 也有專門的 “Accept” 頭部,用於指定客户端可以識別和接受的媒體類型。簡單來説,服務器會使用客户端請求的其中一種媒體類型返回資源表示形式。
但是,如果雙方無法協商出雙方都能使用的通用類型,Spring 將拋出 HttpMediaTypeNotAcceptableException 異常。
3. 實際示例
讓我們創建一個簡單的示例,以演示此場景。
我們將使用 POST 端點——它只能與 <em“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");
}然後,讓我們使用 CURL 發送一個請求,其中 Content-Type 未被識別:
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我們收到的回覆是:
< HTTP/1.1 406
< Content-Length: 04. 解決方案
解決問題的唯一方法是發送/接收一種受支持的類型。
我們能做的只是提供更詳細的消息(默認情況下 Spring 返回一個空主體),並通過自定義的 ExceptionHandler 通知客户端所有可接受的媒體類型。
在我們的情況下,只有 “application/json”:
@ResponseBody
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
public String handleHttpMediaTypeNotAcceptableException() {
return "acceptable MIME type:" + MediaType.APPLICATION_JSON_VALUE;
}