java

SpringBootアプリにBootstrap4を追加(WebJars使用)

投稿日:2019年7月1日

SpringBootにCSSやJSを追加する場合は概ね以下のパターンがあるんじゃないかと思います。(bowerはもう使わない方向で)

  1. CDNで外部から読み込む<script src=”JSのURL”> <link href=”CSSのURL”>
  2. ダウンロードしてきてsrc/main/resources/staticに配置する
  3. Node.jsを併用してnpmインストールする
  4. Node.jsを併用してWebpackなどのバンドラで纏めて読み込む
  5. WebJarsを使ってMaven的に内部に持つ

それぞれのメリット、デメリットを見て行きます。

メリット、デメリット

1.CDNで外部から読み込む

メリット:
インストールはHTMLへのコピペのみで簡単。ネットワーク帯域を節約できる。

デメリット:
CDNに障害が発生した場合など、外因性の障害が発生する危険が0じゃない。

2.ダウンロードしてきてsrc/main/resources/staticに配置

メリット:
開発システム内で完結する。1のデメリットが解消される。

デメリット:
自前でダウンロードしてきて配置する必要がある。

3.Node.jsを併用してnpmインストールする

メリット:
npm install一発でインストール可能。バージョン管理も出来る。

デメリット:
Node.jsが必要。node_modulesがwarに入ってしまってサイズがデカくなる。

4.Node.jsを併用してWebpackなどのバンドラで纏めて読み込む

メリット:
JS、CSS、画像、等々の資源を一つに纏められ、<script>タグが一つで済む。

デメリット:
Node.jsが必要になる。読み込みは1資源で良いがサイズが大きくなり、非SPAの場合、ページによっては不要な資源を読み込むことになる。

5.WebJarsを使ってMaven的に内部に持つ

メリット:
MavenがWeb資源もバージョン管理してくれる。開発システム内、Javaのみで完結する。

デメリット:
仕組みが若干トリッキーでWebJarsを知らないと最初「?」てなる。

目立ったデメリットが無く、Javaプログラマが普段通りの感覚でWebコンポーネントを管理できるWebJarsは、生粋のJavaプロジェクトでは良い選択肢になりそうです。

WebJarsとは

みんな大好きMavenやGradleで、開発システムにCSS、JSをインストール出来るようになります。

com.webjars.{JSやCSSプロダクト}をインストールすることで/webjarsコンテキストが自動で作られ、そこでJSやCSSを公開してくれるようになります。

pom.xml等での依存の指定の仕方はWebJarsの公式サイトを参照します。

メジャー処のプロダクトをMavenやGradleで依存追加する方法が書いてあります。Filesを見ることで実際にリンクする時のパスも分かります。

WebJarsでBootstrap4を入れる

前回作ったSpringBoot + JSP雛型プロジェクトに入れてみます。

pom.xmlにBootstrap4を追加。依存するjQueryも追加。MavenのartifactバージョンがJSライブラリのバージョンと同じなのは分かり易くていいですね。

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.4.1</version>
        </dependency>

SpringBootを起動し、公開されたwebjarsコンテキストからlogin.jspで資源を読み込みます。ブラウザで読み込んでみて開発者ツールでエラーが出ていなければOKです。

<%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SpringBoot + JSP</title>

<script src="webjars/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="webjars/bootstrap/4.3.1/css/bootstrap.min.css"/>
<script src="webjars/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
    <% out.println(new java.util.Date()); %>
</body>
</html>

SpringMVCとBootstrap4でログイン遷移を作ってみる

bootstrap4も使えるようになったのでログイン画面を実装し、遷移する処理を入れてみます。

JS、CSSをロードするインクルードJSPを作成

今回はSPA(シングルページアプリケーション)ではないので画面全体が遷移します。各画面で一々JSやCSSを読み込む手間を省く為のインクルードJSPを作っておきます。

src/main/webapp/WEB-INF/view/head.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%>

<meta charset="UTF-8">

<script src="webjars/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="webjars/bootstrap/4.3.1/css/bootstrap.min.css" />
<script src="webjars/bootstrap/4.3.1/js/bootstrap.min.js"></script>

<title>SpringBoot + Bootstrap4</title>

ログイン画面入力フォームを作成

ログイン画面のEmail、Passwordを受け取るFormを作成します。

package com.example.demo;

public class DemoForm {
	private String email;

	private char[] password;

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public char[] getPassword() {
		return password;
	}

	public void setPassword(char[] password) {
		this.password = password;
	}
}

コントローラに画面遷移を追加

コントローラに/loginハンドラを追加してresult.jspにフォワード出来るようにしておきます。DemoFormも登録しておきます。

loginメソッドではDemoFormからログイン画面の入力値を受け取り、次のresult.jspに渡すModelに値を再設定しています。単純なエコー処理です。

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class DemoController {

    // 追加
    @ModelAttribute
    public DemoForm setUpForm() {
        return new DemoForm();
    }

    @RequestMapping(path = "/", method = { RequestMethod.GET })
    public String input(Model model) {
        return "login";
    }

    // 追加
    @RequestMapping(path = "/login", method = { RequestMethod.POST })
    public String login(DemoForm demoForm, Model model) {

        model.addAttribute("email", demoForm.getEmail());
        model.addAttribute("password", new String(demoForm.getPassword()));

        return "result";
    }
}

ログイン後の遷移先JSPを作成

遷移先のresult.jspをsrc/main/webapp/WEB-INF/viewに作成します。コントローラから受け取ったemailとpasswordを表示しています。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<!DOCTYPE html>
<html>
<head>
<%@ include file="/WEB-INF/view/head.jsp"%>
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
            <a class="navbar-brand" href="#">SpringBoot + Bootstrap4</a>
        </nav>
    </header>

    <div style="margin-left: 100px; margin-right: 100px; margin-top: 100px;">
        <p>Email : ${email}</p>
        <p>Password : ${password}</p>
    </div>
</body>
</html>

ログインページを再作成

最後に時刻を出すだけだったlogin.jspをログインページとして作り直します。「Sign in」ボタンがクリックされるとDemoControllerの/loginが呼ばれるようにしておきます。form内の入力値がDemoFormクラスに渡されるようにmodelAttribute属性も忘れずに。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<!DOCTYPE html>
<html>
<head>
<%@ include file="/WEB-INF/view/head.jsp"%>
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
            <a class="navbar-brand" href="#">SpringBoot + Bootstrap4</a>
        </nav>
    </header>

    <div style="margin-left: 100px; margin-right: 100px; margin-top: 100px;">
        <form:form action="/login" method="POST" class="form-signin"
            modelAttribute="demoForm">
            <div class="text-center mb-4">
                <h3>ログイン</h3>
            </div>

            <div class="form-label-group">
                <label for="inputEmail">Eメールアドレス</label>
                <form:input path="email" class="form-control" placeholder="Email"></form:input>
            </div>

            <div class="form-label-group">
                <label for="inputPassword">パスワード</label>
                <form:password path="password" class="form-control"
                    placeholder="Password"></form:password>
            </div>

            <div class="checkbox mb-3">
                <label> <input type="checkbox" value="remember-me">
                    パスワードを記憶
                </label>
            </div>
            <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
        </form:form>
    </div>
</body>
</html>

動作確認

ブラウザでhttp://localhost:8080にアクセスしてBootstrap4でデザインされた画面が表示されることを確認し、適当な値を入力して「Sign in」ボタンをクリックします。

遷移先のresult.jsp。login.jspで入力された画面が表示されていれば動確完了です。

まとめ

WebJarsを使うとMavenでCSSやJSが自動インストール出来ることが分かりました。入れたものを使いこなすのはまた別問題ですが、管理自体は大分整然としますね。

-java
-, ,

執筆者:

関連記事

ブラウザでRSA暗号化したデータをサーバで復号する(Angular + JSEncrypt、Spring MVC)【前編】

セキュリティ的にクリティカルなデータをクライアントブラウザで暗号化保存するようにしてみます。 通信経路はHTTPSで暗号化されていてもスマホに重要なデータが平文で残っていたら珠に傷です。 目次1 環境 …

Javascript(暗号化JSライブラリ「Forge」)とp12ファイルで署名値を作成、Javaで検証する

前回、送信データの改ざんを検知する為、簡易的なセキュリティトークンであるPKCS#12形式のファイルを作成しました。 One IT Thing  10 Pockets開発用のPKCS#12フ …

Stripe+Java+Payment Request APIでApple Pay、Google Payを使ったテストWeb決済をしてみる

自分で作ったサービスを運用してチャリンチャリンしたい・・・エンジニアならこんな夢、一度は見たことがあるんじゃないでしょうか。 夢を実現する為、以前Stripeのcheckout.jsを使ったテストWe …

Jerseyで開発したRESTで任意リファラからのCORSアクセスを許可する

package jp.hoge.filter; import java.util.Properties; import javax.servlet.http.HttpServletRequest; i …

H2 Databaseで生成したSHA256値をJavaで生成したSHA256値と比較してみる

ファイル、サーバ、メモリ、様々な動作形態がとれてプロトタイピングや、配布アプリの組み込みDBとして便利に使えるPure Javaデータベースの「H2」。 h2database.com  2 …

 

shingo.nakanishi
 

東京在勤、1977年生まれ、IT職歴2n年、生涯技術者として楽しく生きることを目指しています。デスマに負けず健康第一。