SpringBootをVSCodeで使ってみる

# 導入

## 拡張機能のインストール

以下の拡張機能をインストールします。
Javaを使うのでJava系の拡張機能がまとまっている[Java Extension Pack](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack)と、SpringBootの拡張機能がまとまっている[Spring Boot Extension Pack](https://marketplace.visualstudio.com/items?itemName=Pivotal.vscode-boot-dev-pack)を入れます。必要に応じて不要な拡張機能は無効にしてください。

- Java Extension Pack
  - Language Support for Java
  - Debugger for Java
  - Java Test Runner
  - Maven for Java
  - Java Dependency Viewer
  - Visual Studio IntelliCode
- Spring Boot Extension Pack
  - Spring Boot Tools
  - Concourse CI Pipeline Editor
  - Cloudfoundry Manifest YML Support
  - Spring Intializr Java Support
  - Spring Boot Dashboard



## プロジェクトの作成

Spring Boot Tools を入れたことで、VSCodeでSpringBootのコマンドが使えるようになっています。

### コマンド
 
コマンドパレットで`Spring Initializr: Generate a Maven Project`を実行（対話式でプロジェクトを作成していきます）

- `Java`を選択
- パッケージ名を入力（例．com.example）
- プロジェクト名を入力
- SpringBootのバージョンを選択
- 依存関係を選択
    - web
    - thymeleaf
- プロジェクトの保存先を選択

### ディレクトリ構成

  ```none:ディレクトリ構成
  src/
    └ main/
    │  ├ java/
    │  │  └ com/
    │  │     └ example/
    │  │        └ {アプリケーション名}/
    │  │          └ DemoApplication.java
    │  └ resource/
    │     ├ static/
    │     └ templates/
    └ test/
  target/
  .gitignore
  mvnw
  mvnw.cmd
  pom.xml
  ```

## アプリケーション実行

### `src/main/java/com/example/{アプリケーション名}/controller`ディレクトリにIndexController.java を作成

  ```java:IndexController.java
  package com.example.{アプリケーション名}.controller;
  
  import org.springframework.stereotype.Controller;
  import org.springframework.ui.Model;
  import org.springframework.web.bind.annotation.RequestMapping;
  
  @Controller
  public class IndexController {
  
      @RequestMapping("/")
      public String index(Model model) {
          model.addAttribute("msg", "Hello");
          return "index";
      }
  }
  ```

### `src/main/resources/templates`ディレクトリにindex.htmlを作成

  ```html:index.html
  <!DOCTYPE html>
  <html>
  <head>
      <title>ホーム</title>
  </head>
  <body>
      <div>
          <p>コンテンツ</p>
      </div>
  </body>
  </html>
  ```

### `デバッグ > デバッグの開始` を選択

  - 環境の選択で`java`を選択(初回のみ)
  - `launch.json`が生成される(初回のみ)
  - 再度、`デバッグ > デバッグの開始`を選択(初回のみ)

### http://localhost:8080/にアクセスする

# ヘッダー・フッターの作成

## 依存関係の追加

SpringBootのテンプレートエンジンであるthymeleafのLayout Dialect機能を使うために依存関係に`thymeleaf-layout-dialect`を追加する。ついでに`bootstrap`と`jquery`も追加する。

- `pom.xml`に以下の内容を追加

  ```xml
  <dependency>
  	<groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
  </dependency>
  
  <dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>3.3.7</version>
  </dependency>
  
  <dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>1.12.4</version>
  </dependency>
  ```

## テンプレートを作成

### 実装

- `src/main/resources/template/layouts/layout.html`を作成する。

  ```html
  <!DOCTYPE html>
  <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:th="http://www.thymeleaf.org"
          xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
  <head>
      <title layout:title-pattern="$CONTENT_TITLE | $LAYOUT_TITLE">Thymeleaf de layout</title>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link rel="stylesheet" media="all" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}" />
      <link rel="stylesheet" media="all" th:href="@{/css/style.css}" />
  </head>
  <body>
      <div layout:replace="~{layouts/header::header}"></div>
  
      <div id="content" class="clearfix">
          <div class="container">
              <div layout:fragment="content" th:remove="tag"></div>
          </div>
      </div>
      <div layout:replace="~{layouts/footer::footer}"></div>
  
      <!-- scripts -->
      <script type="text/javascript" th:src="@{/webjars/jquery/1.12.4/jquery.min.js}"></script>
      <script type="text/javascript" th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>
  </body>
  </html>
  ```

  

#### `src/main/resources/template/layouts/header.html`を作成する。

  ```html:header.html
  <!DOCTYPE html>
  <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:th="http://www.thymeleaf.org"
          xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
  <body>
      <nav class="navbar navbar-default" layout:fragment="header">
          <div class="container-fluid">
              <div class="navbar-header">
                  <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navigation">
                      <span class="icon-bar"></span>
                      <span class="icon-bar"></span>
                      <span class="icon-bar"></span>
                  </button>
                  <a class="navbar-brand" href="/">SpringBoot練習</a>
              </div>
              <div class="collapse navbar-collapse" id="navigation">
                  <p class="navbar-text navbar-right">ログイン中</p>
              </div>
          </div>
      </nav>
  </body>
  </html>
  ```

  

#### `src/main/resources/template/layouts/footer.html`を作成する。

  ```html:footer.html
  <!DOCTYPE html>
  <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:th="http://www.thymeleaf.org"
          xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
  <body>
      <div id="footer" layout:fragment="footer">
          <footer class="text-center">
              <small class="text-muted">Copyright(C) koukibuu3, All rights reserved.</small>
          </footer>
      </div>
  </body>
  </html>
  
  ```



#### `src/main/resources/templates/index.html`を以下のように修正する。

  ```html:index.html
  <!DOCTYPE html>
  <html
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layouts/layout}">
  
  <head>
      <title>ホーム</title>
  </head>
  <body>
      <div layout:fragment="content">
          <p>コンテンツ</p>
      </div>
  </body>
  </html>
  ```

  

### 解説

`layouts/header.html`に以下を記入することで、

```html:header.html(一部)
<div layout:fragment="header"><!-- 内容 --></div>
```

`layout.html`に記入した以下のタグが置き換わる。

```html:layout.html(一部)
<div layout:replace="~{layouts/header::header}"></div>
```

※ `th:replace`の代わりに`th:include`を使用することで、`layout.html`のタグの内部を書き換える。



レイアウトを読み込む個別ページ側(index.html)で以下の記述をすることで、`layouts/layout.html`の記述を反映することができる。

```html:index.html(一部)
<html
    xmlns:th="http://www.thymeleaf.org"
    xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
    layout:decorate="~{layouts/layout}">
```