はじめに
Spring Bootの学習として、外部APIを呼び出して画面に表示する簡単なサンプルを作成しました。
今回は、無料で使える天気APIである Open-Meteo を使い、東京付近の現在の天気情報を取得して、ブラウザに表示します。
最初はJSONをそのまま表示するだけでもよいのですが、今回は少し実務寄りに、
- Controller
- Service
- データ保持用クラス
- HTMLテンプレート
に分けて、MVCに近い形で作成します。
環境
今回の環境は以下です。
OS:Windows11
IDE:Eclipse 2026
Java:Java SE 21
Spring Boot:4.1.0
ビルドツール:Maven
テンプレートエンジン:Thymeleaf
JSON処理:Jackson
Spring Boot 4系では、Jacksonのimportが従来の記事と違い、以下のようになる場合があります。
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
古い記事では以下のように書かれていることが多いです。
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
私の環境では、Eclipseの自動補完により tools.jackson.databind が使われました。
作成するもの
ブラウザで以下にアクセスすると、
http://localhost:8080/weather-view
天気情報が画面に表示されるようにします。
表示する内容は以下です。
時刻
気温
風速
風向き
天気コード
使用するAPI
今回はOpen-Meteoの天気APIを使います。
東京付近の現在の天気を取得するURLは以下です。
https://api.open-meteo.com/v1/forecast?latitude=35.68&longitude=139.76¤t_weather=true&timezone=Asia/Tokyo
パラメータの意味は以下です。
latitude=35.68
→ 緯度。東京付近を指定
longitude=139.76
→ 経度。東京付近を指定
current_weather=true
→ 現在の天気情報を取得する
timezone=Asia/Tokyo
→ 日本時間で取得する
プロジェクト作成時に選ぶもの
EclipseでSpring Bootプロジェクトを作成します。
ファイル
→ 新規
→ Spring スターター・プロジェクト
設定例は以下です。
プロジェクト名:SampleAPIWeb
Type:Maven
Java Version:21
Packaging:Jar
Language:Java
依存関係は以下を選びました。
Spring Web
Thymeleaf
Lombok
Spring Boot DevTools
それぞれの役割は以下です。
Spring Web
→ ControllerやWeb APIを作るために必要
Thymeleaf
→ HTMLテンプレートを使うために必要
Lombok
→ getterやコンストラクタを短く書くために使用
Spring Boot DevTools
→ 開発時の再起動などを便利にするもの
最終的なファイル構成
今回作成するファイルは以下です。
src/main/java/com/example/demo
├─ WeatherController.java
├─ WeatherService.java
└─ WeatherInfo.java
src/main/resources/templates
└─ weather.html
役割は以下です。
WeatherController.java
→ ブラウザからのアクセスを受け取る
WeatherService.java
→ Open-Meteo APIを呼び出す
WeatherInfo.java
→ 天気情報を入れるデータ用クラス
weather.html
→ 画面表示を担当するHTML
1. WeatherInfo.javaを作成する
まず、天気情報をまとめて持つためのクラスを作ります。
場所:
src/main/java/com/example/demo
ファイル名:
WeatherInfo.java
コードは以下です。
package com.example.demo;
import lombok.AllArgsConstructor;
import lombok.Getter;
// HTMLに渡す天気情報をまとめるためのクラス
// WeatherServiceで取得した値を、このクラスに入れてControllerへ返す
@Getter
@AllArgsConstructor
public class WeatherInfo {
// 天気データの時刻
private String time;
// 気温
private double temperature;
// 風速
private double windspeed;
// 風向き
private int winddirection;
// 天気コード
private int weathercode;
}
補足:@Getterとは
@Getter
を付けることで、以下のようなgetterメソッドを自動生成してくれます。
getTime()
getTemperature()
getWindspeed()
getWinddirection()
getWeathercode()
そのため、自分でgetterを書く必要がありません。
補足:@AllArgsConstructorとは
@AllArgsConstructor
を付けることで、全フィールドを引数に持つコンストラクタを自動生成してくれます。
つまり、以下のようなコンストラクタを書かなくてもよくなります。
public WeatherInfo(String time, double temperature, double windspeed, int winddirection, int weathercode) {
this.time = time;
this.temperature = temperature;
this.windspeed = windspeed;
this.winddirection = winddirection;
this.weathercode = weathercode;
}
今回は、作成後に値を書き換える必要がないため、setterは作成していません。
2. WeatherService.javaを作成する
次に、外部APIを呼び出す処理を担当するServiceクラスを作ります。
場所:
src/main/java/com/example/demo
ファイル名:
WeatherService.java
コードは以下です。
package com.example.demo;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
// 外部APIを呼び出して、天気情報を取得するクラス
@Service
public class WeatherService {
public WeatherInfo getWeather() throws Exception {
// 外部APIを呼び出すためのRestClientを作成する
RestClient restClient = RestClient.create();
// Open-MeteoのAPIを呼び出し、結果をJSON文字列として取得する
String result = restClient.get()
.uri("https://api.open-meteo.com/v1/forecast?latitude=35.68&longitude=139.76¤t_weather=true&timezone=Asia/Tokyo")
.retrieve()
.body(String.class);
// JSON文字列をJavaで扱いやすい形に変換する
ObjectMapper mapper = new ObjectMapper();
// resultに入っているJSON文字列をJsonNodeに変換する
JsonNode root = mapper.readTree(result);
// JSONの中から current_weather の部分だけ取り出す
JsonNode currentWeather = root.get("current_weather");
// current_weather の中から必要な値を取り出す
String time = currentWeather.get("time").asText();
double temperature = currentWeather.get("temperature").asDouble();
double windspeed = currentWeather.get("windspeed").asDouble();
int winddirection = currentWeather.get("winddirection").asInt();
int weathercode = currentWeather.get("weathercode").asInt();
// 取得した値をWeatherInfoに詰めて返す
return new WeatherInfo(time, temperature, windspeed, winddirection, weathercode);
}
}
補足:@Serviceとは
@Service
このクラスが「業務処理を担当するクラス」であることをSpringに伝えるアノテーションです。
今回でいうと、WeatherService は、
外部APIを呼び出す
JSONを解析する
必要な値を取り出す
WeatherInfoに詰める
という処理を担当しています。
3. WeatherController.javaを作成する
次に、ブラウザからのアクセスを受け取るControllerを作ります。
場所:
src/main/java/com/example/demo
ファイル名:
WeatherController.java
コードは以下です。
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
// 画面表示を担当するController
@Controller
public class WeatherController {
private final WeatherService weatherService;
// コンストラクタ
// SpringがWeatherServiceを自動で渡してくれる
public WeatherController(WeatherService weatherService) {
this.weatherService = weatherService;
}
// http://localhost:8080/weather-view にアクセスされたときに実行される
@GetMapping("/weather-view")
public String showWeather(Model model) throws Exception {
// Serviceを使って天気情報を取得する
WeatherInfo weatherInfo = weatherService.getWeather();
// HTML側で使えるように、weatherInfoという名前でデータを渡す
model.addAttribute("weatherInfo", weatherInfo);
// templates/weather.html を表示する
return "weather";
}
}
補足:@Controllerとは
@Controller
このクラスが画面表示用のControllerであることを示します。
JSONや文字列をそのまま返す場合は、
@RestController
を使います。
今回はHTMLを表示したいので、
@Controller
を使っています。
補足:return "weather"; の意味
return "weather";
これは、以下のHTMLファイルを表示するという意味です。
src/main/resources/templates/weather.html
weather.html の拡張子は書かずに、weather とだけ指定します。
4. weather.htmlを作成する
最後に、ブラウザに表示するHTMLファイルを作ります。
場所:
src/main/resources/templates
もし templates フォルダがなければ作成します。
ファイル名:
weather.html
コードは以下です。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>天気情報</title>
<style>
body {
font-family: sans-serif;
background-color: #f5f8fb;
margin: 40px;
}
.card {
background-color: white;
border-radius: 12px;
padding: 24px;
width: 380px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
h1 {
font-size: 24px;
margin-bottom: 20px;
}
.item {
font-size: 18px;
margin: 12px 0;
}
.label {
font-weight: bold;
}
</style>
</head>
<body>
<div class="card">
<h1>現在の天気</h1>
<div class="item">
<span class="label">時刻:</span>
<span th:text="${weatherInfo.time}"></span>
</div>
<div class="item">
<span class="label">気温:</span>
<span th:text="${weatherInfo.temperature}"></span> ℃
</div>
<div class="item">
<span class="label">風速:</span>
<span th:text="${weatherInfo.windspeed}"></span> km/h
</div>
<div class="item">
<span class="label">風向き:</span>
<span th:text="${weatherInfo.winddirection}"></span> °
</div>
<div class="item">
<span class="label">天気コード:</span>
<span th:text="${weatherInfo.weathercode}"></span>
</div>
</div>
</body>
</html>
補足:th:textとは
<span th:text="${weatherInfo.temperature}"></span>
これは、Controllerから渡された weatherInfo の temperature を表示するという意味です。
Java側では以下のようにデータを渡しています。
model.addAttribute("weatherInfo", weatherInfo);
そのためHTML側で、
${weatherInfo.temperature}
のように書くことで値を表示できます。
5. 実行する
Spring Bootのメインクラスを右クリックして実行します。
実行
→ Spring Boot アプリケーション
起動できたら、ブラウザで以下にアクセスします。
http://localhost:8080/weather-view
天気情報がカード形式で表示されれば成功です。
全体の処理の流れ
今回の処理の流れは以下です。
ブラウザで /weather-view にアクセス
↓
WeatherController がリクエストを受け取る
↓
WeatherService がOpen-Meteo APIを呼び出す
↓
JSONから必要な値を取り出す
↓
WeatherInfo に値を入れる
↓
Controller が weather.html に値を渡す
↓
HTMLに天気情報が表示される
躓いたところ・注意点
1. pom.xmlではなくbuild.gradleがある場合
Spring Bootプロジェクト作成時に Gradle を選ぶと、pom.xml ではなく build.gradle が作成されます。
今回はMavenで作成したため、pom.xml が作られました。
Maven → pom.xml
Gradle → build.gradle
学習動画が pom.xml 前提の場合は、プロジェクト作成時に Maven を選ぶと混乱しにくいです。
2. Jacksonのimportが記事と違う場合がある
Spring Boot 4系では、以下のimportになりました。
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
古い記事では以下のように書かれていることがあります。
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
Eclipseの自動補完や保存時の自動修正に従うと、正しいimportに直してくれる場合があります。
3. @RestControllerと@Controllerの違い
JSONや文字列をそのまま返す場合は、
@RestController
を使います。
HTMLテンプレートを表示する場合は、
@Controller
を使います。
今回のように weather.html を表示する場合は @Controller を使います。
まとめ
今回は、Spring BootでOpen-Meteoの天気APIを呼び出し、取得したデータをHTML画面に表示しました。
学習した内容は以下です。
Spring Bootプロジェクトの作成
外部APIの呼び出し
JSONデータの取得
JSONから必要な値を取り出す方法
Controller / Service / データクラス / HTML の役割分担
Thymeleafを使った画面表示
1つのJavaファイルに全部書くのではなく、役割ごとにファイルを分けることで、処理の流れが分かりやすくなりました。