GoogleマップをWebページに表示する(Spring Boot + Thymeleaf)


概要

Spring Bootの学習をしていて、Google MapをWebページに表示したいなという事でMaps JavaScript APIを使用してみました。
今回はThymeleafのフラグメントを使用して、ホーム画面にGoogle Map表示します。
htmlファイルにjavascript、cssも埋め込んでしまえば公式のサンプルソースで一瞬だったのですが、
それぞれ別ファイルで読込しつつ、フラグメントも使用するとどこで読込すれば良いのかが分からずつまずきました。(というかjavascriptは結局html埋込にしました。。)
※GCPの設定方法は省略しています。

環境

  • macOS Catalina
    • Version: 10.15.7
  • Eclipse IDE for Enterprise Java Developers.
    • Version: 2020-03 (4.15.0)
    • STSプラグイン
  • Spring Boot 2.2.6
  • Java8
  • Maven

参考サイト

フォルダ構成

見易くする為いくつか割愛して載せています。

src
└── main/
    ├── java/
    │   └── com/
    │       └── example/
    │           └── demo/
    │               ├── SampleApplication.java
    │               ├── WebConfig.java
    │               └── login/
    │                   └── controller/
    │                       └── HomeController.java
    └── resources/
        ├── application.properties
        ├── static/
        │   └── css/
        │       └── home.css
        └── templates/
            └── login/
                ├── homeLayout.html
                └── shopMap.html

メインの画面です。この中の<div th:include="__${contents}__"></div>の箇所に、Google Mapを記述しているshopMap.htmlをフラグメントでincludeして表示したい訳です。
shopMap.cssはここで読込しています。

homeLayout.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
    xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <meta charset="UTF-8"></meta>
    <link th:href="@{/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css}" rel="stylesheet"></link>
    <script th:src="@{/webjars/jquery/1.11.1/jquery.min.js}"></script>
    <script th:src="@{/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js}"></script>
    <link th:href="@{/css/home.css}" rel="stylesheet"></link>
    <title>Home</title>
</head>
<body>

・・・省略・・・

    <!-- コンテンツ-->
    <div class="container-fluid">
        <div class="row">
            <div class="col-sm-10 col-sm-offset-2 main">
                <div th:include="__${contents}__"></div>
            </div>
        </div>
    </div>
</body>
</html>

これがGoogle Mapを実際に記述するhtmlです。
YOUR_API_KEYの箇所を自身がGCPで取得したAPI キーに書き換えます。
最初ここでshopMap.cssの読込をしてしまっていましたが上手く表示されませんでした。
おそらくフラグメントで<div th:fragment="shop_map">の部分だけhomeLayout.htmlにincludeされる
為、ここの<head>タグでcssを読み込んでも無意味だったのかもしれません。

shopMap.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
</head>

<body>
    <div th:fragment="shop_map">

    ・・・省略・・・

        <!-- 地図を表示する div 要素 -->
        <div id="map"></div>
        <script>
          var map;
          function initMap() {
            map = new google.maps.Map(document.getElementById('map'), {
              center: {lat: -34.397, lng: 150.644},
              zoom: 10
            });
          }
        </script>
        <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" defer></script>
    </div>
</body>
</html>

CSSはこれだけだが、必須とのこと。

home.css
#map {
  height: 400px;
  width: 600px;
}

最後に、コントローラクラスでGetメソッドの処理を追加します。
modelに指定したいフラグメントを追加して、homeLayout.htmlを返します。

HomeController.java
package com.example.demo.login.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
    @GetMapping("/shopMap")
    public String getShopMap(Model model) {
        model.addAttribute("contents", "login/shopMap :: shop_map");
        return "login/homeLayout";
    }
}

Spring Bootを起動してhttp://localhost:8080/shopMapにアクセスします。
※GCPのキー制限の設定は「HTTP リファラー(ウェブサイト)」で、http://localhost/*のみ指定しています。

無事出ました!

最後に

そもそもAPIを初めて使用してみましたが、Maps JavaScript APIは地図の表示だけであればとても簡単ですし、これをカスタマイズしていけば楽しみながら色々と学んでいけそうです。
最初に記述した通り、javascriptは結局外部ファイルとして読み込むと上手く動かず、、どこでimportすべきか今回は分かりませんでした。
開発を進めてもう少し理解が深まったらまた挑戦してみようと思います。
その時にこの未完成の記事を完成させる為、恐縮ながら一旦投稿させて頂きますm(._.)m