[初心者向け] Spring MVC + JSP + Bootstrap 3 の使い方（Getting Start編）

最近お仕事で、Spring MVC(TERASOLUNA 5)アプリにCSSフレームワークを適用する方法を教える機会があったので、TERASOLUNA 5でオススメしているBootstrap 3を例にとって、適用方法を解説してみたいと思います。

アプリのベースとしては、TERASOLUNA 5のブランクプロジェクトを使用しますが、基本的にSpring MVCアプリには適用できます。

## 今回使用するライブラリ

* TERASOLUNA GFW 5.4.1.RELEASE
  - Spring MVC 4.3.14.RELEASE
* Bootstrap 3.3.7
* JQuery Bootstrap 3.3.1

> 執筆時点で、Bootstrapの最新verは4.1.3です。HTMLに適用するクラス名に違いはありますが、基本的に同じノリで適用できるはずですが、マイグレーションが難しそうなら別に記事を書くかもしれません。

## Bootstrapを適用する

Bootstrapに限らず、CSSフレームワークを適用するには、だいたい以下のステップを踏みます。

* HTMLからCSSファイルを読み込む
* HTMLタグの`class`属性に、CSSフレームワークで定義されたクラス名を指定する

> BootstrapはリッチUIを実現するため、CSS+JSファイルで構成されていて、JSファイルはJQueryに依存しています。

CSSファイルの読み込みには、3つほど方法があります。

* CDN（Web上に公開されているファイル）からCSSファイルを読み込む
* アプリに配置したCSSファイルを読み込む
* WebJarsを利用してCSSファイルを読み込む

この方法別に、Bootstrapを適用していきます。

### CDNからBootstrapを読み込む

CDNはWeb上に公開されているため、開発者がCSSファイルをダウンロードや管理する必要がないのが良いところです。
ただし、アプリ利用者のネットワーク状況に応じて参照できない場合があるため、イントラや商用アプリ等では確実性には欠けます。

* JSPファイル

```html
<html>
<head>
<!-- (1) -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
    <!-- (2) -->
    <div id="wrapper" class="container-fluid">
        <h1>Hello world!</h1>
    </div>
</body>
</html>

```

(1)
**CDNのURLを指定して、BootstrapのCSSファイルとJSファイル、JQueryのJSファイルを読み込みます。**
CDNのURLは公式リファレンス（[Bootstrap CDN](https://getbootstrap.com/docs/3.3/getting-started/#download-cdn)、[JQyery CDN](https://code.jquery.com/)）にあります。

(2) 
**`body`直下の`div`タグに`class="container-fluid"`を追加します。**

`container`クラスはコンテンツをセンター寄りに整える役割を果たしますが、`container-fluid`クラスは画面の大きさに合わせて、画面いっぱいにコンテンツを表示することができます。

> TERASOLUNA 5のマルチモジュールブランクプロジェクトであれば、Tilesが適用されているので、template.jspに適用することになります。

### アプリに配置したBootstrapを読み込む

事前にCSSファイルをダウンロードしてアプリに配置しておき、それを参照します。
TERASOLUNA 5では`<mvc:resources>`タグが設定済みで、`src/main/webapp/resources`ディレクトリに配置したCSSファイルが自動的に公開されます。

> 一般的には、CSSファイルなどの静的リソースはアプリで公開するのではなく、WebサーバやAPサーバで公開します。

* Bean定義ファイル（spring-mvc.xml）

```xml
    <mvc:resources mapping="/resources/**"
        location="/resources/,classpath:META-INF/resources/"
        cache-period="#{60 * 60}" />
```

特に設定を変更する必要はありません。

* ディレクトリ構成

```
src/main/webapp/
 - resouces/app/
   - css/
     - bootstrap.min.css
     - bootstrap.min.css.map
   - fonts/
     - glyphicons-halflings-regular.eot
     - glyphicons-halflings-regular.svg
     - glyphicons-halflings-regular.ttf
     - glyphicons-halflings-regular.woff
     - glyphicons-halflings-regular.woff2
   - js/
     - bootstrap.min.js
     - jquery.min.js
     - jquery.min.map
```

**ダウンロードしたBootstrapとJQueryを`src/main/webapp/resources/app`ディレクトリにコピーします。**

「css」にはCSSファイル、「js」にはJSファイルを配置します。「fonts」にはCSSで使用するアイコンが格納されます。JSPから直接使用することはありませんが、必要なファイルです。

ファイル名に「min」とついているのは、ソースコードのスペースなどを削除して軽量化したファイルです。「min」がつかないファイルはCSSやJSのデバッグをしないのであれば、必要ありません。


* JSPファイル

```html
<html>
<head>
<!-- (1) -->
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/app/css/bootstrap.min.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/app/js/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/app/js/bootstrap.min.js"></script>
</head>
<body>
    <!-- (2) -->
    <div id="wrapper" class="container-fluid">
        <h1>Hello world!</h1>
    </div>
</body>
</html>
```

(1)
**アプリケーションが公開するパスを指定して、BootstrapのCSSファイルとJSファイル、JQueryのJSファイルを読み込みます。**

CDNとは違い、EL式を利用してアプリケーション内のパスを指定していることが分かると思います。

(2)
`class="container-fluid"`はCDNと同じなので、説明しません。

### WebJarsを利用してBootstrapを読み込む

[WebJars](https://www.webjars.org/)を利用して、MavenでCSSやJSファイルを取得して自動的にアプリに組み込むことができます。
WebJarsで取得したCSSファイル等を公開するには、`<mvc:resources>`タグの設定を変更する必要があります。

> WebJarsで取得できるものはメジャーなライブラリに限られているので、WebJarsで必要なファイルをすべて取得できるかどうか確認したうえで使いましょう。

* Maven設定ファイル（pom.xml）

```xml
        <!-- == Begin WebJars == -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1-1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7-1</version>
        </dependency>
        <!-- == End WebJars == -->
```

`dependencies`タグ内に`webjars-locator`とBootstrapとJQueryを追加します。

> TERASOLUNA 5のマルチモジュールブランクプロジェクトなら、ルートPOMの`dependencyManagement`にバージョンまで定義し、webプロジェクトPOMの`dependencies`ではバージョンを省略しましょう。

* Bean定義ファイル（spring-mvc.xml）

```xml
    <mvc:resources mapping="/resources/**"
        location="/resources/,classpath:META-INF/resources/,/webjars/"
        cache-period="#{60 * 60}">
        <mvc:resource-chain resource-cache="true" />
    </mvc:resources>
```

**`<mvc:resources>`タグの`location`に`/webjars/`を追加します。**
**`<mvc:resources>`タグ内に`<mvc:resource-chain>`タグを追加します。**

WebJarsで取得したCSSファイル等を、`<mvc:resource-chain>`タグが自動的に`/webjars/[artifactId]`ディレクトリに配置してくれます。これらのファイルを、他の静的リソースを同様に`/resources`パスで公開しています。

* JSPファイル

```html
<html>
<head>
<!-- (1) -->
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/bootstrap/css/bootstrap.min.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/jquery/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <!-- (2) -->
    <div id="wrapper" class="container-fluid">
        <h1>Hello world!</h1>
    </div>
</body>
</html>
```

(1)
**アプリケーションが公開するパスを指定して、BootstrapのCSSファイルとJSファイル、JQueryのJSファイルを読み込みます。**

`/resources`パス以降が分からなくなったら、依存ライブラリからBootstrap等のJarファイルを開いて確認してみてください。

(2)
`class="container-fluid"`はCDNと同じなので、説明しません。

## 動作確認する

アプリケーションを起動して、ブラウザでページを開いてください。
ブラウザの開発者ツールから「ネットワーク」を確認して、参照ファイルの取得が「200 OK」になっていれば、正常にBootstrapが適用されています。

試しにJSPの`link`タグや`src`タグを消したりつけたりしてみると、「Hello World!」の文字フォントが変わっていることが確認できると思います。

## まとめ

今回は、Spring MVC(TERASOLUNA 5)アプリに3つの方法でBootstrap 3を適用する方法をまとめてみました。
次回は、Bootstrap 3を利用した入力フォームの実装方法についてまとめます。

## 参考資料

* [Bootstrap 3 Docs / Getting Start](https://getbootstrap.com/docs/3.3/getting-started/)