🤯

Jsonを使用した外部APIとの接続

2021/12/07に公開

特定の検索ワードを入れた値の一覧取得と詳細ページの表示までを目標とする。

手順1 : ホットペッパーAPI利用できる様手続きを行う。
手順2 : ホットペッパーAPIを使用してコンソール上にデータをJson形式で表示する
手順3 : Json形式で取得したデータをJacksonを使用してJavaオブジェクトに変換
手順4 : コントローラからthymeleafを使用してブラウザ上に情報を表示させる

手順1 : ホットペッパーAPI利用できる様手続きを行う。

まずは登録が必要なので登録を行いAPIキーを取得する。
https://webservice.recruit.co.jp/register/

手順2 : ホットペッパーAPIを使用してコンソール上にデータをJson形式で表示する

まずはブラウザ検索してみる

この様にAPIキーがないとうまくいかないため入れて再度実施

データが取得できたところでこのデータをコンソール上に出力していく

controller.java
@GetMapping("/locations")
public String locations(Model model) throws IOException {
  // リクエストを送るURLを定義する(Json形式に値を修正)
  String url = "https://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=a5c3c9fb001ca296&large_area=Z011&budget+codeB008&results_available&format=json";
  // http通信を行う
  OkHttpClient client = new OkHttpClient();
  // リクエストの作成
  Request request = new Request.Builder().url(url).build();
  // レスポンスの取得
  Response response = client.newCall(request).execute();
  // レスポンスのBody要素を取得
  String responseBody = response.body().string();
  System.out.println(responseBody);
}

これで取得したJson形式の値が表示される

手順3 : Json形式で取得したデータをJacksonを使用してJavaオブジェクトに変換

controller.java
@GetMapping("/locations")
public String locations(Model model) throws IOException {
  // リクエストを送るURLを定義する(Json形式に値を修正)
  String url = "https://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=a5c3c9fb001ca296&large_area=Z011&budget+codeB008&results_available&format=json";
  // http通信を行う
  OkHttpClient client = new OkHttpClient();
  // リクエストの作成
  Request request = new Request.Builder().url(url).build();
  // レスポンスの取得
  Response response = client.newCall(request).execute();
  // レスポンスのBody要素を取得
  String responseBody = response.body().string();
  System.out.println(responseBody);
  
  ObjectMapper mapper = new ObjectMapper();
  ShopsInfo shopsInfo = mapper.readValue(responseBody, ShopsInfo.class);
  System.out.println(shopsInfo.results.shops.get(0).address);
}

Jsonを変換するためのShopsInfoクラスを作成しJsonデータとJavaObjectをマッピングさせる
今回レスポンスにcatchという値があったがJavaでは予約語のため使用できない。そのため@JsonPropertyを使用してcatchというレスポンスの場合はcatch_sampleで値を扱う様にする。

Genre.java
public class Genre {
  @JsonProperty("catch")
  public String catch_sample; // catchが使えない
  public String code;
  public String name;
}

手順4 : コントローラからthymeleafを使用してブラウザ上に情報を表示させる

引数にmodelを追加してshopsInfoというobjectをthymeleaf上で扱える様に値を渡してあげる
またtemplate直下にLocations.htmlがある場合そこを返り値を設定する。

controller.java
@GetMapping("/locations")
public String locations(Model model) throws IOException {
  String url = "https://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=a5c3c9fb001ca296&large_area=Z011&budget+codeB008&results_available&format=json";
  OkHttpClient client = new OkHttpClient();
  Request request = new Request.Builder().url(url).build();
  Response response = client.newCall(request).execute();
  String responseBody = response.body().string();
  ObjectMapper mapper = new ObjectMapper();
  ShopsInfo shopsInfo = mapper.readValue(responseBody, ShopsInfo.class);
  model.addAttribute("shopsInfo", shopsInfo);
  return "Locations";
}

返却されたレスポンスボディの中に複数のshop情報が入っているので取り出して表示する。

locations.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Locations</title>
</head>
<body>
<div>
</div>
    <h2>LocationsPage</h2>
</body>
    <th:block th:each="shop : ${shopsInfo.results.shops}">
        <form action="details" method="get">
            <input type="text" name="shopId" th:value="*{shop.id}" />
            <input type="submit" />
        </form>

        <p th:text="${shop.access}" name="access"></p>
        <p th:text="${shop.address}"></p>
        <p th:text="${shop.band}"></p>
        <p th:text="${shop.barrier_free}"></p>

        <p th:text="${shop.budget.average}"></p>
        <p th:text="${shop.budget.code}"></p>
        <p th:text="${shop.budget.name}"></p>

        <p th:text="${shop.budget_memo}"></p>
        <p th:text="${shop.capacity}"></p>
        <p th:text="${shop.card}"></p>
        <p th:text="${shop.catch_sample}"></p>
        <p th:text="${shop.charter}"></p>
        <p th:text="${shop.child}"></p>
        <p th:text="${shop.close}"></p>

        <p th:text="${shop.coupon_urls.pc}"></p>
        <p th:text="${shop.coupon_urls.sp}"></p>

        <p th:text="${shop.course}"></p>
        <p th:text="${shop.english}"></p>
        <p th:text="${shop.free_drink}"></p>
        <p th:text="${shop.free_food}"></p>

        <p th:text="${shop.genre.catch_sample}"></p>
        <p th:text="${shop.genre.code}"></p>
        <p th:text="${shop.genre.name}"></p>

        <p th:text="${shop.horigotatsu}"></p>
        <p th:text="${shop.id}"></p>
        <p th:text="${shop.karaoke}"></p>
        <p th:text="${shop.ktai_coupon}"></p>

        <p th:text="${shop.large_area.code}"></p>
        <p th:text="${shop.large_area.name}"></p>

        <p th:text="${shop.large_service_area.code}"></p>
        <p th:text="${shop.large_service_area.name}"></p>

        <p th:text="${shop.lat}"></p>
        <p th:text="${shop.lng}"></p>
        <p th:text="${shop.logo_image}"></p>
        <p th:text="${shop.lunch}"></p>

        <p th:text="${shop.middle_area.code}"></p>
        <p th:text="${shop.middle_area.name}"></p>

        <p th:text="${shop.midnight}"></p>
        <p th:text="${shop.mobile_access}"></p>
        <p th:text="${shop.name}"></p>
        <p th:text="${shop.name_kana}"></p>
        <p th:text="${shop.non_smoking}"></p>
        <p th:text="${shop.open}"></p>
        <p th:text="${shop.other_memo}"></p>
        <p th:text="${shop.parking}"></p>
        <p th:text="${shop.party_capacity}"></p>
        <p th:text="${shop.pet}"></p>

        <p th:text="${shop.photo.mobile.l}"></p>
        <p th:text="${shop.photo.mobile.s}"></p>
        <p th:text="${shop.photo.pc.l}"></p>
        <p th:text="${shop.photo.pc.m}"></p>
        <p th:text="${shop.photo.pc.s}"></p>

        <p th:text="${shop.private_room}"></p>

        <p th:text="${shop.service_area.code}"></p>
        <p th:text="${shop.service_area.name}"></p>

        <p th:text="${shop.shop_detail_memo}"></p>
        <p th:text="${shop.show}"></p>

        <p th:text="${shop.small_area.code}"></p>
        <p th:text="${shop.small_area.name}"></p>

        <p th:text="${shop.station_name}"></p>

        <p th:text="${shop.sub_genre.code}"></p>
        <p th:text="${shop.sub_genre.name}"></p>

        <p th:text="${shop.tatami}"></p>
        <p th:text="${shop.tv}"></p>

        <p th:text="${shop.urls.pc}"></p>

        <p th:text="${shop.wedding}"></p>
        <p th:text="${shop.wifi}"></p>
        <hr />
    </th:block>
</html>

参考資料,使用した言語やAPI等..

言語:Java
フレームワーク:SpringBoot
外部API:ホットペッパーAPI
Jsonを扱うライブラリ:Jackson
プラスαの参考資料
HTTP/HTTP2.0を扱うライブラリ:OKHttp
プラスαの参考資料
テンプレートエンジン:Thymeleaf
プラスαの参考資料
プラスαの参考資料

Discussion