JSONってなに?ブラウザとサーバーのやり取りの基本をやさしく解説
新人
「先輩、Webアプリの開発でよく出てくる『JSON』ってなんですか?Springの講習で見かけたんですが、よくわからなくて…」
先輩
「ああ、JSONは今のWeb開発では欠かせないデータ形式なんだ。サーバーとブラウザがやり取りする時によく使われるよ。」
新人
「HTMLじゃだめなんですか?なんでJSONを使う必要があるんでしょう?」
先輩
「その疑問はすごく大事だね。順番に説明していくよ!」
1. JSONとは?(概要と意味)
JSON(ジェイソン)とは、「JavaScript Object Notation(ジャバスクリプト・オブジェクト・ノーテーション)」の略で、データをテキスト形式で表現するためのフォーマットです。構文がシンプルで人間にも読みやすく、プログラムでも扱いやすいという特徴があります。
たとえば、サーバーとブラウザがデータをやり取りするとき、SpringのREST APIでJSON形式のデータを返すことがよくあります。以下は、JSONの基本的な構造です。
{
"name": "Tanaka",
"age": 28,
"email": "tanaka@example.com"
}
このように、キーと値のペアで情報を持っていて、文字列、数値、配列、オブジェクトなどを柔軟に組み合わせることができます。
Springアプリケーションでは、たとえば以下のようなコントローラでJSONレスポンスを返すことができます。
@Controller
public class UserController {
@ResponseBody
@GetMapping("/user")
public Map<String, Object> getUser() {
Map<String, Object> data = new HashMap<>();
data.put("name", "Tanaka");
data.put("age", 28);
data.put("email", "tanaka@example.com");
return data;
}
}
このコードを実行すると、ブラウザやクライアントアプリは、上記のようなJSON形式のデータを受け取ることができます。
2. なぜHTMLではなくJSONを使うのか?
昔はサーバーがHTMLを生成して、そのままブラウザに送っていました。しかし、今ではフロントエンドとバックエンドが役割分担するようになり、データだけをやり取りするのが一般的になっています。
たとえば、ReactやVue.jsなどのJavaScriptフレームワークでは、HTMLの表示はブラウザ側が担当します。そのため、サーバーはHTMLではなく「データ」だけをJSON形式で提供するようになりました。
さらに、JSONは構造が明確で軽量なため、通信の効率も良く、モバイルアプリやSPA(シングルページアプリケーション)でも広く使われています。
実際にブラウザとサーバーがJSONを使ってやり取りする様子を、SpringのREST APIを使って再現してみましょう。
@Controller
public class ProductController {
@ResponseBody
@GetMapping("/product")
public Map<String, Object> getProduct() {
Map<String, Object> product = new HashMap<>();
product.put("id", 101);
product.put("name", "ノートパソコン");
product.put("price", 85000);
return product;
}
}
このエンドポイントにブラウザでアクセスすると、次のようなJSONが表示されます。
{"id":101,"name":"ノートパソコン","price":85000}
このように、ブラウザ側は受け取ったJSONを使って、画面上に動的に表示を更新できます。HTMLは見た目を作るもので、JSONは中身のデータを届ける役割、という風に分かれていると考えるとわかりやすいでしょう。
Springを使ったWebアプリケーションでは、@ResponseBodyを使うことで、HTMLではなくJSONでレスポンスを返す仕組みが自然に作れます。
3. JSONの基本的な構造(オブジェクトと配列の使い方)
JSONのデータは、大きく分けて「オブジェクト」と「配列」という2つの構造で成り立っています。これらを組み合わせることで、複雑なデータもわかりやすく表現できます。
まず「オブジェクト」は、キーと値のペアを中括弧{ }で囲んだ構造です。先ほどの例のように、ユーザーの名前や年齢などの情報をひとまとまりにできます。
{
"name": "Yamada",
"age": 30,
"email": "yamada@example.com"
}
次に「配列」は、同じ種類のデータをリストのように並べるときに使います。角括弧[ ]で囲み、複数のオブジェクトを入れることができます。
[
{
"name": "Yamada",
"age": 30
},
{
"name": "Suzuki",
"age": 25
}
]
このような構造は、たとえばユーザー一覧や商品一覧をサーバーからブラウザへ渡すときによく使われます。SpringのREST APIで配列のJSONを返す場合も、とても自然に扱えます。
4. SpringでJSONをレスポンスとして返す方法
SpringのWebアプリケーションでは、クラスに@Controllerをつけてルーティングを設定し、メソッドに@ResponseBodyをつけることで、HTMLではなくJSON形式のレスポンスを返すことができます。
たとえば、次のようにJavaのMapを使ってJSONを返す方法があります。
@Controller
public class InfoController {
@ResponseBody
@GetMapping("/info")
public Map<String, Object> getInfo() {
Map<String, Object> data = new HashMap<>();
data.put("status", "ok");
data.put("version", "1.0.0");
return data;
}
}
このコントローラを実行して、ブラウザで/infoにアクセスすると、サーバーからJSON形式のレスポンスが返ってきます。
{"status":"ok","version":"1.0.0"}
このように、@ResponseBodyを使うだけで、SpringはMapやListを自動的にJSONに変換してくれます。特別な設定や外部ライブラリを追加しなくても、Gradleで作成したプロジェクト内でそのまま利用できます。
5. @Controller + @ResponseBodyでオブジェクトを返す方法
Springでは、MapだけでなくJavaのクラスを作って、それをそのままJSONとして返すこともできます。こうすることで、より明確にデータの構造を定義でき、保守性も高くなります。
まず、次のようにクラスを作成します。
public class Book {
private String title;
private String author;
private int price;
// ゲッターとセッター
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
次に、このBookオブジェクトをコントローラでJSONとして返すようにします。
@Controller
public class BookController {
@ResponseBody
@GetMapping("/book")
public Book getBook() {
Book book = new Book();
book.setTitle("Spring入門");
book.setAuthor("佐藤太郎");
book.setPrice(3200);
return book;
}
}
このエンドポイントにブラウザからアクセスすると、以下のようなJSONレスポンスが表示されます。
{"title":"Spring入門","author":"佐藤太郎","price":3200}
このように、Springでは@Controllerと@ResponseBodyを組み合わせることで、オブジェクトをJSONに変換してレスポンスとして返すことができます。これにより、REST APIの設計もシンプルかつ明確になります。
特に、SpringのプロジェクトをpleiadesとGradleで開発する場合でも、複雑な設定をしなくても標準の構成で簡単にJSONを扱えるのが大きなメリットです。
6. フロントエンドからリクエストを送る流れ(fetchやフォーム送信)
次は、ブラウザ側からサーバーへリクエストを送る方法について見ていきましょう。特に最近では、JavaScriptのfetchを使って、非同期的にサーバーへHTTPリクエストを送信する場面が増えています。
たとえば、ユーザー情報をJSON形式でサーバーに送信したいとき、以下のようなコードになります。
fetch("/submit", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "田中太郎",
age: 28
})
})
.then(response => response.json())
.then(data => {
console.log("レスポンス:", data);
});
このように、JavaScriptのfetch関数を使うと、簡単にサーバーと通信できます。Content-Typeヘッダーをapplication/jsonにすることで、JSONデータとして送信されるようになります。
一方で、従来のHTMLフォームを使った送信では、application/x-www-form-urlencodedという形式が使われていて、JSONとは形式が異なります。そのため、JSONを使いたい場合はfetchやAxiosなどのJavaScriptライブラリを使うのが一般的です。
7. Springで受け取ってJSONで返す処理の全体像
ここでは、ブラウザから送信されたJSONをSpring側で受け取り、加工してJSONでレスポンスを返すまでの流れを見ていきましょう。Gradleで作成したSpringプロジェクトでは、特別な設定なしでJSONを扱うことができます。
まず、受け取るデータのクラスを用意します。
public class UserRequest {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
次に、コントローラを作成してPOSTリクエストを受け取るようにします。
@Controller
public class SubmitController {
@ResponseBody
@PostMapping("/submit")
public Map<String, Object> submit(@RequestBody UserRequest user) {
Map<String, Object> response = new HashMap<>();
response.put("message", user.getName() + "さん、年齢は" + user.getAge() + "歳ですね。");
response.put("status", "受信成功");
return response;
}
}
@RequestBodyを使うことで、ブラウザから送られてきたJSONをJavaオブジェクトに変換できます。そして、@ResponseBodyでJavaのMapをそのままJSONレスポンスとして返せます。
このように、SpringのREST APIでは、受信からレスポンスまで一貫してJSONで処理できるため、フロントエンドとサーバーの連携が非常にスムーズです。
8. よくあるミスや初心者のつまずき(文字化け、構文エラーなど)
Springとブラウザ間でJSONをやり取りする際、初心者がよくつまずくポイントがいくつかあります。ここでは代表的なミスを紹介し、その対処法も合わせて説明します。
● JSONの構文エラー
JSONは非常に厳密な構文ルールがあります。たとえば、キー名や文字列は必ずダブルクォートで囲む必要があります。
// ❌ 間違った例
{
name: "Tanaka",
age: 28
}
// ✅ 正しい例
{
"name": "Tanaka",
"age": 28
}
カンマの付け忘れや、波かっこの開きと閉じが一致していない場合もエラーの原因になります。エディタのJSONフォーマッタ機能を使うと、こうしたミスを防ぎやすくなります。
● 文字化け(特に日本語)
日本語が文字化けするケースも多いです。SpringではデフォルトでUTF-8が使われるため、HTMLやJavaScript側もUTF-8に統一するように設定しましょう。
<meta charset="UTF-8">
fetchを使うときも、Content-TypeヘッダーにUTF-8を指定することで、文字化けを防ぐことができます。
headers: {
"Content-Type": "application/json; charset=UTF-8"
}
● @RequestBodyがうまく機能しない
POSTリクエストでJSONを受け取る際、@RequestBodyがついていない、または送信側のContent-Typeがapplication/jsonでないと、データが正しくバインドされません。
エラー例として、Spring側でオブジェクトがnullになってしまうケースがあります。こうしたときは、リクエストヘッダーや受信クラスのフィールド名を再確認しましょう。
特にGradleで作成したSpringプロジェクトでは、Jacksonライブラリが自動で組み込まれているため、基本的な設定ミスさえ避ければJSONの受信はスムーズに行えます。