Spring BootとjQuery/fetchでJSON送受信！POST・GET通信で画面を動的に更新する方法

# Spring BootとjQuery/fetchでJSON送受信！POST・GET通信で画面を動的に更新する方法

この記事では、Spring BootのREST APIに対して、jQueryやfetch APIを使ってPOST（およびGET）通信を行い、JSONデータを送受信しながら画面を動的に更新する方法を紹介します。

---

## 1. Spring Boot側のRESTコントローラー作成

まず、Spring BootでREST APIを作成します。ここでは、

+ GETリクエストでユーザー情報を返す
+ POSTリクエストでJSON形式のユーザー情報を受け取り、受け取った内容をレスポンスとして返す

という簡単なAPIを用意します。

```java
package com.example.demo.controller;

import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
public class UserController {

    // GETリクエスト：ユーザー情報を返す
    @GetMapping("/api/user")
    public Map<String, Object> getUser() {
        return Map.of(
            "name", "山田太郎",
            "age", 30
        );
    }

    // POSTリクエスト：JSONを受け取り、ユーザー作成（擬似処理）
    @PostMapping("/api/user")
    public Map<String, Object> createUser(@RequestBody Map<String, Object> userData) {
        String name = (String) userData.get("name");
        Integer age = null;
        // ageはNumber型で来るのでキャストに注意
        Object ageObj = userData.get("age");
        if (ageObj instanceof Integer) {
            age = (Integer) ageObj;
        } else if (ageObj instanceof Number) {
            age = ((Number) ageObj).intValue();
        }

        // ここでDB保存などの処理を実装可能

        return Map.of(
            "message", "ユーザー作成成功",
            "name", name,
            "age", age
        );
    }
}
```
---
## 2. フロント側（HTML + jQuery）でのPOST/GET通信

次に、ユーザーの名前と年齢を入力し、ボタン操作でサーバーにGETやPOST通信を行い、戻ってきたJSONデータを画面に表示する例です。
+ パターン１

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>jQueryでPOSTとGET通信</title>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>

  <h2>ユーザー情報取得（GET）</h2>
  <button id="getUserBtn">ユーザー情報を取得</button>
  <div id="getResult" style="margin-bottom:30px;"></div>

  <h2>ユーザー作成フォーム（POST）</h2>
  <label>名前: <input type="text" id="nameInput" /></label><br />
  <label>年齢: <input type="number" id="ageInput" /></label><br />
  <button id="submitBtn">送信</button>

  <div id="postResult" style="margin-top:20px;"></div>

  <script>
    $(function() {
      // GET通信
      $('#getUserBtn').click(function() {
        $.ajax({
          url: '/api/user',
          type: 'GET',
          dataType: 'json',
          success: function(response) {
            $('#getResult').html(
              '<p>名前: ' + response.name + '</p>' +
              '<p>年齢: ' + response.age + '</p>'
            );
          },
          error: function() {
            $('#getResult').text('GET通信エラーが発生しました。');
          }
        });
      });

      // POST通信
      $('#submitBtn').click(function() {
        const name = $('#nameInput').val();
        const age = Number($('#ageInput').val());

        const dataToSend = { name: name, age: age };

        $.ajax({
          url: '/api/user',
          type: 'POST',
          contentType: 'application/json',
          data: JSON.stringify(dataToSend),
          dataType: 'json',
          success: function(response) {
            $('#postResult').html(
              '<p>' + response.message + '</p>' +
              '<p>名前: ' + response.name + '</p>' +
              '<p>年齢: ' + response.age + '</p>'
            );
          },
          error: function() {
            $('#postResult').text('POST通信エラーが発生しました。');
          }
        });
      });
    });
  </script>

</body>
</html>
```

+ パターン２
```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>jQueryでPOSTとGET通信</title>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>

  <h2>ユーザー情報取得（GET）</h2>
  <button id="getUserBtn">ユーザー情報を取得</button>
  <div id="getResult" style="margin-bottom:30px;"></div>

  <h2>ユーザー作成フォーム（POST）</h2>
  <label>名前: <input type="text" id="nameInput" /></label><br />
  <label>年齢: <input type="number" id="ageInput" /></label><br />
  <button id="submitBtn">送信</button>

  <div id="postResult" style="margin-top:20px;"></div>

  <script>
    $(function() {
      // GET通信
      $('#getUserBtn').click(function() {
        $.ajax({
          url: '/api/user',
          type: 'GET',
          dataType: 'json'
        })
        .done(function(response) {
          $('#getResult').html(
            '<p>名前: ' + response.name + '</p>' +
            '<p>年齢: ' + response.age + '</p>'
          );
        })
        .fail(function() {
          $('#getResult').text('GET通信エラーが発生しました。');
        });
      });

      // POST通信
      $('#submitBtn').click(function() {
        const name = $('#nameInput').val();
        const age = Number($('#ageInput').val());

        const dataToSend = { name: name, age: age };

        $.ajax({
          url: '/api/user',
          type: 'POST',
          contentType: 'application/json',
          data: JSON.stringify(dataToSend),
          dataType: 'json'
        })
        .done(function(response) {
          $('#postResult').html(
            '<p>' + response.message + '</p>' +
            '<p>名前: ' + response.name + '</p>' +
            '<p>年齢: ' + response.age + '</p>'
          );
        })
        .fail(function() {
          $('#postResult').text('POST通信エラーが発生しました。');
        });
      });
    });
  </script>

</body>
</html>
```

### ポイント

+ `$.ajax()`でAPIと通信します

+ `GET`は単純に情報取得

+ `POST`はJSON形式でデータをサーバーに送り、レスポンスを受け取ります

+ 成功したら画面の内容を書き換えて表示します

---

## 3. フロント側（HTML + fetch API）でのPOST/GET通信

jQueryを使わず、fetch APIを使った同様の実装例です。

```java
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <title>fetch APIでPOSTとGET通信</title>
</head>
<body>

  <h2>ユーザー情報取得（GET）</h2>
  <button id="getUserBtn">ユーザー情報を取得</button>
  <div id="getResult" style="margin-bottom:30px;"></div>

  <h2>ユーザー作成フォーム（POST）</h2>
  <label>名前: <input type="text" id="nameInput" /></label><br />
  <label>年齢: <input type="number" id="ageInput" /></label><br />
  <button id="submitBtn">送信</button>

  <div id="postResult" style="margin-top:20px;"></div>

  <script>
    // GET通信
    document.getElementById('getUserBtn').addEventListener('click', () => {
      fetch('/api/user')
        .then(response => {
          if (!response.ok) throw new Error('通信失敗');
          return response.json();
        })
        .then(data => {
          document.getElementById('getResult').innerHTML =
            `<p>名前: ${data.name}</p><p>年齢: ${data.age}</p>`;
        })
        .catch(() => {
          document.getElementById('getResult').textContent = 'GET通信エラーが発生しました。';
        });
    });

    // POST通信
    document.getElementById('submitBtn').addEventListener('click', () => {
      const name = document.getElementById('nameInput').value;
      const age = Number(document.getElementById('ageInput').value);

      fetch('/api/user', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify({ name, age })
      })
      .then(response => {
        if (!response.ok) throw new Error('通信失敗');
        return response.json();
      })
      .then(data => {
        document.getElementById('postResult').innerHTML =
          `<p>${data.message}</p><p>名前: ${data.name}</p><p>年齢: ${data.age}</p>`;
      })
      .catch(() => {
        document.getElementById('postResult').textContent = 'POST通信エラーが発生しました。';
      });
    });
  </script>

</body>
</html>
```
### ポイント

+ `fetch()`はブラウザ標準のAPIで、Promiseで通信を扱います

+ jQueryなしで使えるので、モダンな開発に向いています

+ POST時は`headers`に`Content-Type: application/json`を指定し、`body`にJSON文字列を設定