Spring MVCのHttpMediaTypeNotAcceptableException

Spring MVCのHttpMediaTypeNotAcceptableException

1. 概要

この簡単な記事では、HttpMediaTypeNotAcceptableException例外を確認し、発生する可能性のあるケースを理解します。

2. 問題

Springを使用してAPIエンドポイントを実装する場合、通常、消費/生成されたメディアタイプを指定する必要があります(consumesおよびproducesパラメーターを使用)。 これにより、特定の操作のためにAPIがクライアントに返す可能性のある形式が絞り込まれます。

HTTPには専用の“Accept”ヘッダーもあります。これは、クライアントが認識して受け入れることができるメディアタイプを指定するために使用されます。 簡単に言えば、サーバーは、クライアントが要求したメディアタイプの1つを使用してリソース表現を送り返します。

ただし、両側で使用できる共通のタイプがない場合、SpringはHttpMediaTypeNotAcceptableException例外をスローします。

3. 実用例

このシナリオを示す簡単な例を作成しましょう。

POSTエンドポイントを使用します。これは“application/json _“ _でのみ機能し、JSONデータも返します。

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

次に、認識されないコンテンツタイプで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

得られた応答は次のとおりです。

< HTTP/1.1 406
< Content-Length: 0

4. ソリューション

この問題を解決する唯一の方法は、サポートされているタイプの1つを送受信することです。

私たちにできることは、すべての受け入れ可能なメディアタイプについてクライアントに通知するカスタムExceptionHandlerを使用して、より説明的なメッセージ(デフォルトではSpringは空の本文を返します)を提供することです。

私たちの場合、それは“application/json”だけです:

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

5. 結論

このチュートリアルでは、クライアントが要求するものとサーバーが実際に生成できるものとの間に不一致がある場合にSpring MVCによってスローされるHttpMediaTypeNotAcceptableException例外について検討しました。

いつものように、記事で言及されているコードスニペットはour GitHub repositoryにあります。