Java | Web 基礎・HTTP・REST:HTTP 詳細 - Accept

Java Java
スポンサーリンク

Accept を一言でいうと

Accept ヘッダーは
「サーバーさん、レスポンスは“この種類のデータ”で返してくれると嬉しいです、という希望を伝えるヘッダー」
です。

クライアント(ブラウザやアプリ)が
「JSON が欲しいのか」「HTML が欲しいのか」「画像が欲しいのか」
をサーバーに伝えるための“希望表明”だと思ってください。


Content-Type との違いからイメージする

Content-Type は「今送っている中身はこれです」

まず、よくセットで出てくる Content-Type を思い出しましょう。

Content-Type は、
「このリクエスト(またはレスポンス)のボディは、こういう種類のデータです」
という“事実の宣言”でした。

例:JSON を送るとき

POST /api/users HTTP/1.1
Content-Type: application/json

{"name":"Alice"}
HTTP

これは
「今送っているボディは JSON ですよ」
という意味です。

Accept は「こういう形式で返してほしいです」

一方 Accept は、
「レスポンスは、この種類のデータで返してほしいです」
という“希望”を伝えます。

例:JSON で返してほしいとき

GET /api/users/1 HTTP/1.1
Accept: application/json
HTTP

これは
「ユーザー 1 の情報をください。できれば JSON で欲しいです」
という意味になります。

サーバーはこれを見て、
「じゃあ JSON で返そう」と判断し、

HTTP/1.1 200 OK
Content-Type: application/json

{"id":1,"name":"Alice"}
HTTP

のように返します。

まとめると:
Content-Type → “今送っている中身はこれ”
Accept → “返してほしい中身はこれ”


Accept の基本的な書き方

メディアタイプを列挙する

Accept には、欲しいメディアタイプ(MIME タイプ)を書きます。

一番シンプルな例はこれです。

Accept: application/json
HTTP

「JSON で返してほしい」です。

HTML が欲しいなら

Accept: text/html
HTTP

画像なら

Accept: image/png
HTTP

のように書きます。

複数候補を並べることもできる

「これが第一希望だけど、ダメならこれでもいいよ」と
複数書くこともできます。

Accept: application/json, text/plain
HTTP

この場合、
「JSON がいいけど、無理ならプレーンテキストでもいいよ」
という意味になります。

さらに細かく「優先度(重み)」も付けられますが、
初心者のうちは「とりあえず application/json を指定する」くらいで十分です。


サーバー側は Accept をどう使うか

コンテンツネゴシエーションという考え方

サーバーは、
「自分が返せる形式」と
「クライアントの Accept」
を見比べて、
どの形式で返すかを決めます。

これを「コンテンツネゴシエーション」と呼びます。

例えば、サーバーが

JSON と HTML の両方で返せるエンドポイント

を持っているとします。

クライアント A:

Accept: application/json
HTTP

クライアント B:

Accept: text/html
HTTP

このときサーバーは、

A には JSON を
B には HTML を

返す、ということができます。
同じ URL でも、Accept によって“見え方”を変えられるわけです。

Java(Spring)でのイメージ

Spring MVC では、
produces 属性やメッセージコンバータの設定によって、
「どの Content-Type で返すか」を制御できます。

例えば、JSON 専用の API なら、

@GetMapping(value = "/api/users/{id}", produces = "application/json")
public UserResponse get(@PathVariable Long id) { ... }
Java

のようにしておけば、
基本的に application/json で返す前提になります。

実務では、
「API は JSON 固定」
「画面は HTML 固定」
ということが多いので、
Accept をガチガチに使い分ける場面はそこまで多くありません。

それでも、
「クライアントが Accept で希望を出し、サーバーが Content-Type で応える」
という構図を理解しておくと、プロトコルの見え方が一段クリアになります。


Java 開発者視点での Accept の使いどころ

自分がクライアントになるときに意識する

Java で外部の REST API を叩くとき、
「JSON で返してほしい」のに Accept を付け忘れると、
相手が HTML や XML を返してくることがあります。

WebClientRestTemplate を使うとき、

webClient.get()
        .uri("/api/users/1")
        .accept(MediaType.APPLICATION_JSON)
        .retrieve()
        .bodyToMono(UserResponse.class);
Java

のように accept(MediaType.APPLICATION_JSON) を付けると、
HTTP の Accept: application/json に対応します。

これで、
「このクライアントは JSON を期待しているんだな」
と相手に伝えられます。

ブラウザは自動で Accept を付けてくれる

ブラウザからのアクセスでは、
ブラウザが自動で Accept を付けてくれます。

例えば、普通に URL を開くときは、
text/html を含む Accept が送られます。

逆に、JavaScript の fetch で JSON API を叩くときは、
フロント側で Accept: application/json を付けることが多いです。

バックエンドを書くときに
「ブラウザはこういう Accept を送ってくるんだな」
とログを眺めてみると、理解が一気に深まります。


初心者向けまとめ:Accept を自分の言葉で説明するなら

あなたの言葉で整理すると、こうなります。

Accept は、
「クライアントがサーバーに対して、レスポンスはこの形式で返してほしいと希望を伝えるヘッダー」で、
Accept: application/json なら「JSON で返してほしい」、
Accept: text/html なら「HTML で返してほしい」という意味になる。

Content-Type が「今送っている中身の種類」を表すのに対して、
Accept は「これから受け取りたい中身の種類」を表す。

Java で外部 API を叩くときに Accept: application/json を付けることで、
「JSON を期待している」という意図を相手に伝えられるようになる。

もしよければ、
「同じ /users/1 に対して、HTML で返すパターンと JSON で返すパターン」を
Accept と Content-Type の組み合わせでどう表現するか、
自分の言葉で書き分けてみて。
そこを説明できるようになったとき、Accept はもう“謎のヘッダー”ではなく、“会話の希望を伝える道具”になっているはず。

タイトルとURLをコピーしました