前回は return "Hello, Spring Boot!" で文字列を返しました。実際の Web アプリでは、文字列ではなくデータを JSON 形式で返すのが一般的です。今回は Java のオブジェクトを JSON として返す API を作ります。
Java オブジェクトが JSON に変わる仕組み
Spring Boot では、メソッドの戻り値に Java オブジェクトを指定すると、自動的に JSON に変換してブラウザに返します。この変換は Spring Boot に組み込まれた Jackson というライブラリが担当します。開発者が変換処理を書く必要はありません。
Java オブジェクト → (Jackson が自動変換) → JSON → ブラウザに返す
Employee クラスを作る
返すデータの入れ物として、Employee クラスを作ります。src/main/java/com/example/demo/ に Employee.java を作成します。
package com.example.demo;
public class Employee {
private Integer id;
private String name;
private String department;
public Employee(Integer id, String name, String department) {
this.id = id;
this.name = name;
this.department = department;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getDepartment() {
return department;
}
}
Java の回で作った Student クラスと構造は同じです。フィールドを private にし、値を読み取るための getter メソッド(getId、getName、getDepartment)を用意しています。
Jackson はこの getter メソッドを使って JSON のキー名を決めます。getId() → "id"、getName() → "name" という対応です。
1件の Employee を返す API
EmployeeController.java を作成します。
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
@GetMapping("/api/employees/1")
public Employee getOne() {
return new Employee(1, "田中太郎", "開発部");
}
}
return new Employee(...) で Java オブジェクトを返すと、Jackson が自動で JSON に変換します。
アプリを起動してブラウザで http://localhost:8080/api/employees/1 を開きます。
{"id":1,"name":"田中太郎","department":"開発部"}
DB の回で扱った社員テーブルのデータが、JSON の形式で返ってきます。
一覧を返す API
複数件のデータを返す場合は、List を使います。同じ EmployeeController.java にメソッドを追加します。
package com.example.demo;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
@GetMapping("/api/employees/1")
public Employee getOne() {
return new Employee(1, "田中太郎", "開発部");
}
@GetMapping("/api/employees")
public List<Employee> getAll() {
return List.of(
new Employee(1, "田中太郎", "開発部"),
new Employee(2, "鈴木花子", "営業部"),
new Employee(3, "佐藤次郎", "開発部")
);
}
}
List.of(...) は Java 9 以降で使える、固定のリスト作成方法です。Java の ArrayList と似ていますが、あとから要素を追加・削除できない点が異なります。ここでは固定データを返すだけなので List.of で十分です。
再起動してブラウザで http://localhost:8080/api/employees を開きます。
[{"id":1,"name":"田中太郎","department":"開発部"},{"id":2,"name":"鈴木花子","department":"営業部"},{"id":3,"name":"佐藤次郎","department":"開発部"}]
JSON 配列が返ります。JavaScript の回で fetch を使って取得したのと同じ形式です。
fetch で API を呼んでみる
JavaScript の回で JSONPlaceholder から取得したコードを、今度は自分の API に向けて書き換えます。demo プロジェクトの外に HTML ファイルを作ります(たとえばデスクトップに test.html)。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>API テスト</title>
</head>
<body>
<h1>社員一覧</h1>
<ul id="list"></ul>
<script>
const list = document.getElementById('list');
fetch('http://localhost:8080/api/employees')
.then(function(response) {
return response.json();
})
.then(function(employees) {
for (let i = 0; i < employees.length; i++) {
const li = document.createElement('li');
li.textContent = employees[i].name + ' - ' + employees[i].department;
list.appendChild(li);
}
})
.catch(function(error) {
console.log('エラー: ' + error.message);
});
</script>
</body>
</html>
Spring Boot アプリが起動した状態で、この HTML をブラウザで開きます。
ここで1つ問題が起きる可能性があります。ブラウザが CORS エラーを出して、データが表示されないことがあります。CORS は「別のオリジン(アドレス)からの通信を制限する」ブラウザのセキュリティ機能です。HTML ファイルを直接開くと file:// というオリジンになり、http://localhost:8080 にアクセスすることがブロックされます。
今回は「API が正しく JSON を返すか」を先に確かめたいので、一時的に @CrossOrigin を使ってこの制限をゆるめます。最終回では HTML を Spring Boot の static/ フォルダに入れて同じオリジンから配信するため、@CrossOrigin は不要になります。
注意: @CrossOrigin を引数なしで使うと、すべてのオリジンからのアクセスを許可する状態になります。手元での動作確認専用です。公開するアプリには使わないでください。
対策として、EmployeeController.java に @CrossOrigin を追加します。import 行とクラス宣言の2箇所を変更します。
import org.springframework.web.bind.annotation.CrossOrigin; // 追加
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin // 追加
public class EmployeeController {
// メソッドはそのまま
}
追加したら再起動して、HTML を開き直します。社員名と部署が一覧表示されれば、フロントエンドと API の接続ができています。
## 動作確認のポイント
http://localhost:8080/api/employeesでJSON 配列が返るかhttp://localhost:8080/api/employees/1で1件の JSON が返るか- HTML ファイルからfetch で一覧が表示されるか(CORS エラーが出たら
@CrossOriginを確認)
ここまでの整理
| 要素 | 役割 |
|---|---|
| Employee クラス | データの入れ物。フィールド + getter |
@GetMapping | URL とメソッドを対応づける |
| Jackson | Java オブジェクト → JSON の自動変換 |
List.of(...) | 固定データのリストを作る |
@CrossOrigin | 別オリジンからのアクセスを許可 |
次の回へ
http://localhost:8080/api/employees で JSON 配列が返り、HTML ファイルから fetch で社員一覧が表示されれば、この回は完了です。
今のコードはデータをコード内に直書き(ハードコード)しています。次の回では POST / PUT / DELETE の入口を押さえ、そのあとデータベースとつないで動的にデータを管理します。