かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot でメール送信する Web アプリケーションを作る ( その5 )( Controller クラス、Thymeleaf テンプレートファイルの作成 )

概要

Spring Boot でメール送信する Web アプリケーションを作る ( その4 )( HTMLファイルの作成、確認 ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。

    • Controller クラスの作成、Thymeleaf テンプレートファイルの作成 ( この時点でひと通り画面遷移が見られるようにします )
  • 実装の方針として ksbysample-webapp-basic と以下の点を変更しています。

    • web パッケージの下に 1 Controller クラスにつき 1 パッケージ作成するようにしました。各パッケージの中に Controller クラスで使用する Form クラス等も入れるようにします。
    • src/main/resources/templates ディレクトリの下に 1 Controller クラスにつき 1 ディレクトリ作成するようにしました。
    • Spring Boot を調べ始めた時に、Spring Boot ではパッケージは極力作成しないようにするという記述をどこかで見かけたので ksbysample-webapp-basic を作成する時は必要な時以外はパッケージを作らないようにしましたが、いろいろクラスを作ると見にくかったので上記の方針に変更します。
    • また html 内で共通で定義されている css, js ファイルについては、共通ファイルに定義してそのファイルを include するようにしました。

ソフトウェア一覧

参考にしたサイト

  1. Tutorial: Using Thymeleaf - Difference between th:include and th:replace
    http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#difference-between-thinclude-and-threplace

手順

画面毎の URL の決定

各画面の URL は以下のようにします。

画面 アクション URL
共通 「メール送信」メニュークリック /mailsend
「送信済メール検索」メニュークリック /mailsearch
メール送信画面 初期表示 /mailsend
「送信」ボタンクリック /mailsend/send
送信済メール検索画面 初期表示 /mailsearch
「検索」ボタンクリック /mailsearch

1.0.x-makecontroller ブランチの作成

  1. IntelliJ IDEA で 1.0.x-makecontroller ブランチを作成します。

メール送信画面の Controller クラスの作成

  1. src/main/java/ksbysample/webapp/email/web の下に mailsend パッケージを作成します。

  2. src/main/java/ksbysample/webapp/email/web/mailsend の下に MailsendController.java を作成します。作成後、リンク先の内容 に変更します。

メール送信画面の Thymeleaf テンプレートファイルの作成

  1. src/main/resources/templates の下に mailsend ディレクトリを作成します。

  2. /static/mailsend.html を src/main/resources/templates/mailsend の下にコピーします。

  3. メール送信画面が表示されるか確認します。Gradle projects View から bootRun タスクを実行して Tomcat を起動します。

  4. ブラウザを起動し http://localhost:8080/mailsend へアクセスします。画面は表示されず、ログを見ると org.xml.sax.SAXParseException: 要素タイプ"meta"は、対応する終了タグ"</meta>"で終了する必要があります。 のエラーメッセージが出力されていました。

  5. src/main/resources/templates/mailsend の下の mailsend.html を リンク先のその1の内容 に変更します。

  6. ブラウザをリロードします。今度は画面が表示され、ログにもエラーは出力されませんでした。

送信済メール検索画面の Controller クラスの作成

  1. src/main/java/ksbysample/webapp/email/web の下に mailsearch パッケージを作成します。

  2. src/main/java/ksbysample/webapp/email/web/mailsearch の下に MailsearchController.java を作成します。作成後、リンク先の内容 に変更します。

送信済メール検索画面の Thymeleaf テンプレートファイルの作成

  1. src/main/resources/templates の下に mailsearch ディレクトリを作成します。

  2. /static/mailsearch.html を src/main/resources/templates/mailsearch の下にコピーします。

  3. メール送信画面の Thymeleaf テンプレートファイルを作成した時に修正した箇所を修正します。src/main/resources/templates/mailsearch の下の mailsearch.html を リンク先のその1の内容 に変更します。

  4. 送信済メール検索画面が表示されるか確認します。Run View で Ctrl+F5 を押して Tomcat を再起動します。

  5. ブラウザから http://localhost:8080/mailsearch へアクセスします。画面が表示され、ログにエラーも出力されていません。

Thymeleaf テンプレートファイルから共通部分の抽出

  1. src/main/resources/templates の下に common ディレクトリを作成します。

  2. src/main/resources/templates/mailsend の下の mailsend.html を src/main/resources/templates/common の下にコピーし、ファイル名を head-cssjs.html に変更します。head-cssjs.html を リンク先の内容 に変更します。

  3. src/main/resources/templates/mailsend の下の mailsend.html を src/main/resources/templates/common の下にコピーし、ファイル名を mainparts.html に変更します。mainparts.html を リンク先の内容 に変更します。

  4. src/main/resources/templates/mailsend の下の mailsend.html を src/main/resources/templates/common の下にコピーし、ファイル名を bottom-js.html に変更します。bottom-js.html を リンク先の内容 に変更します。

  5. src/main/resources/templates/mailsend の下の mailsend.html を リンク先のその2の内容 に変更します。

  6. ブラウザから http://localhost:8080/mailsend へアクセスし、画面が表示されログにエラーが出力されていないことを確認します。

  7. src/main/resources/templates/mailsearch の下の mailsearch.html を リンク先のその2の内容 に変更します。

  8. ブラウザから http://localhost:8080/mailsearch へアクセスし、画面が表示されログにエラーが出力されていないことを確認します。

  9. メモ書きです。

    • th:replace の存在を初めて知りました。th:include と th:replace を使ってみた感じでは、body タグ内にヘッダやフッタ等の共通部分を読み込み時は th:replace、css/js 等の共通定義ファイルを html 内に読み込む時は th:include を使うのが良さそうな気がします。
  10. Run View で Ctrl+F2 を押して Tomcat を停止します。

commit、Push、Pull Request、マージ

  1. commit します。commit 時に Code Analysis のダイアログが表示され、「Review」ボタンをクリックすると Attribute th:... is not allowed here の Warning が出ていましたので、出なくなるよう対応します。

  2. まず表示されている Warning をダブルクリックして、Warning の原因となっているソースファイルの該当箇所を表示します。

    f:id:ksby:20150418193026p:plain

  3. 該当箇所が表示されたら Alt+Enter キーを押してコンテキストメニューを表示し、「Add th:... to custom html attributes」メニューを選択します。

    f:id:ksby:20150418193943p:plain

  4. 上記の操作を th:action, th:fragment, th:class に対して実行します。

  5. commit、GitHub へ Push、1.0.x-makecontroller -> 1.0.x へ Pull Request、1.0.x でマージ、1.0.x-makecontroller ブランチを削除、をします。

課題&次回は。。。

  • 次回はメール送信処理を実装します。

  • AdminLTE は便利なのですが、IE11 だと左側のメニューで画面を切り替えたり「送信」「検索」ボタンをクリックした時に、毎回左側のメニューが左から右へ動く動作が見られます ( 何か操作する度にひょこひょこ動いてすごく見栄えが悪いです )。Chrome では動かないので、何か対応方法がないか調べてみたいと思います。

ソースコード

MailsendController.java

package ksbysample.webapp.email.web.mailsend;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/mailsend")
public class MailsendController {

    @RequestMapping
    public String index() {
        return "mailsend/mailsend";
    }

    @RequestMapping("/send")
    public String send() {
        return "redirect:/mailsend";
    }

}

mailsend/mailsend.html

■その1

    <meta charset="UTF-8"/>
    <title>ksbysample-webapp-email</title>
    <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'/>
  • 2つある meta タグの最後を >/> へ変更します。

■その2

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>ksbysample-webapp-email</title>
    <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'/>

    <meta th:replace="common/head-cssjs"/>
</head>
<body class="skin-blue">
<div class="wrapper">

    <!-- Main Header -->
    <div th:replace="common/mainparts :: main-header"></div>

    <!-- Left side column. contains the logo and sidebar -->
    <div th:replace="common/mainparts :: main-sidebar (active='mailsend')"></div>

    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <section class="content-header">
            <h1>
                メール送信画面
            </h1>
        </section>

        <!-- Main content -->
        <section class="content">
            <div class="row">
                <div class="col-xs-12">
                    <form id="mailSendForm" method="post" action="/mailsend/send" th:action="@{/mailsend/send}" class="form-horizontal">
                        <!--<div class="callout callout-danger">-->
                            <!--<p>共通エラーメッセージ表示エリア</p>-->
                        <!--</div>-->
                        <div class="box box-primary">
                            <div class="box-body">
                                <div class="form-group">
                                    <label for="from" class="control-label col-sm-2">From</label>
                                    <div class="col-sm-10">
                                        <div class="row"><div class="col-sm-8"><div class="input-group"><span class="input-group-addon"><i class="fa fa-envelope"></i></span><input type="text" name="from" id="from" class="form-control input-sm" value="" placeholder="Fromアドレスを入力して下さい"/></div></div></div>
                                        <!--<div class="row"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div>-->
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label for="to" class="control-label col-sm-2">To</label>
                                    <div class="col-sm-10">
                                        <div class="row"><div class="col-sm-8"><div class="input-group"><span class="input-group-addon"><i class="fa fa-envelope"></i></span><input type="text" name="to" id="to" class="form-control input-sm" value="" placeholder="Toアドレスを入力して下さい"/></div></div></div>
                                        <!--<div class="row"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div>-->
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label for="to" class="control-label col-sm-2">Subject</label>
                                    <div class="col-sm-10">
                                        <div class="row"><div class="col-sm-12"><input type="text" name="subject" id="subject" class="form-control input-sm" value="" placeholder="件名を入力して下さい"/></div></div>
                                        <!--<div class="row"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div>-->
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label for="name" class="control-label col-sm-2">氏名</label>
                                    <div class="col-sm-10">
                                        <div class="row"><div class="col-sm-8"><input type="text" name="name" id="name" class="form-control input-sm" value="" placeholder="(例) 田中 太郎"/></div></div>
                                        <!--<div class="row"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div>-->
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label class="control-label col-sm-2">性別</label>
                                    <div class="col-sm-10">
                                        <div class="row"><div class="col-sm-12">
                                            <div class="radio">
                                                <label><input type="radio" name="sex" value="man"/></label> 
                                                <label><input type="radio" name="sex" value="woman"/></label>
                                            </div>
                                        </div></div>
                                        <!--<div class="row"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div>-->
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label class="control-label col-sm-2">項目</label>
                                    <div class="col-sm-10">
                                        <div class="row"><div class="col-sm-8">
                                            <select name="type" id="type" class="form-control input-sm">
                                                <option>資料請求</option>
                                                <option>商品に関する苦情</option>
                                                <option>その他</option>
                                            </select>
                                        </div></div>
                                        <!--<div class="row"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div>-->
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label class="control-label col-sm-2">商品</label>
                                    <div class="col-sm-10">
                                        <div class="row"><div class="col-sm-12">
                                            <div class="checkbox">
                                                <label><input type="checkbox" name="item" value="1"/>商品1</label> 
                                                <label><input type="checkbox" name="item" value="2"/>商品2</label> 
                                                <label><input type="checkbox" name="item" value="3"/>商品3</label>
                                            </div>
                                        </div></div>
                                        <!--<div class="row"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div>-->
                                    </div>
                                </div>

                                <div class="form-group">
                                    <label for="naiyo" class="control-label col-sm-2">内容</label>
                                    <div class="col-sm-10">
                                        <div class="row"><div class="col-sm-12"><textarea rows="5" name="naiyo" id="naiyo" class="form-control input-sm" placeholder="お問い合わせ内容を入力して下さい"></textarea></div></div>
                                        <!--<div class="row"><div class="col-sm-10"><p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p></div></div>-->
                                    </div>
                                </div>
                            </div>
                            <div class="box-footer">
                                <div class="text-center">
                                    <button type="button" id="send" value="send" class="btn btn-primary">送信</button>
                                </div>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </section>
        <!-- /.content -->
    </div>
    <!-- /.content-wrapper -->

</div>
<!-- ./wrapper -->

<!-- REQUIRED JS SCRIPTS -->

<div th:replace="common/bottom-js"></div>
<script type="text/javascript">
<!--
$(document).ready(function() {
    $('#from').focus();

    $('#send').bind('click', function(){
        $('#mailSendForm').submit();
    });
});
-->
</script>
</body>
</html>
  • <html xmlns="http://www.w3.org/1999/xhtml"><html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> へ変更します。
  • <!-- Bootstrap 3.3.2 --> ... <![endif]--><meta th:replace="common/head-cssjs"/> へ変更します。head タグ内で div タグを使用すると commit 時に Element div is not allowed here の Warning が出ますので、meta タグを使用します。
  • <header class="main-header"> ... </header><div th:replace="common/mainparts :: main-header"></div> へ変更します。
  • <aside class="main-sidebar"> ... </aside><div th:replace="common/mainparts :: main-sidebar (active='mailsend')"></div> へ変更します。
  • <form id="mailForm" method="post" action="/mailsend/send" class="form-horizontal"><form id="mailSendForm" method="post" action="/mailsend/send" th:action="@{/mailsend/send}" class="form-horizontal"> に変更します。
  • <!-- jQuery 2.1.3 --> ... <script src="/js/app.min.js" type="text/javascript"></script><div th:replace="common/bottom-js"></div> へ変更します。
  • </body> の直前に画面独自の Javascript を記述する <script type="text/javascript"> ... </script> を追加します。

MailsearchController.java

package ksbysample.webapp.email.web.mailsearch;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/mailsearch")
public class MailsearchController {

    @RequestMapping
    public String index() {
        return "mailsearch/mailsearch";
    }

}

mailsearch/mailsearch.html

■その1

    <meta charset="UTF-8"/>
    <title>ksbysample-webapp-email</title>
    <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'/>
  • 2つある meta タグの最後を >/> へ変更します。

■その2

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>ksbysample-webapp-email</title>
    <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'/>

    <meta th:replace="common/head-cssjs"/>
    <style>
    <!--
    .form-group {
        margin-bottom: 5px;
    }
    .table {
        margin-top: 10px;
        margin-bottom: 0px;
    }
    .table>tbody>tr>td
    , .table>tbody>tr>th
    , .table>tfoot>tr>td
    , .table>tfoot>tr>th
    , .table>thead>tr>td
    , .table>thead>tr>th {
        padding: 5px;
    }
    -->
    </style>
</head>
<body class="skin-blue">
<div class="wrapper">

    <!-- Main Header -->
    <div th:replace="common/mainparts :: main-header"></div>

    <!-- Left side column. contains the logo and sidebar -->
    <div th:replace="common/mainparts :: main-sidebar (active='mailsearch')"></div>

    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <section class="content-header">
            <h1>
                送信済メール検索画面
            </h1>
        </section>

        <!-- Main content -->
        <section class="content">
            <div class="row">
                <div class="col-xs-12">
                    <div class="box">
                        <div class="box-header with-border bg-purple-gradient">
                            <div class="row">
                                <div class="col-xs-12">
                                    <form id="mailSearchForm" method="post" action="/mailsearch" th:action="@{/mailsearch}" class="form-horizontal">
                                        <div class="form-group">
                                            <label for="to" class="control-label col-sm-2">To</label>
                                            <div class="col-sm-10">
                                                <div class="row"><div class="col-sm-8"><div class="input-group"><span class="input-group-addon"><i class="fa fa-envelope"></i></span><input type="text" name="to" id="to" class="form-control input-sm" value="" placeholder=""/></div></div></div>
                                            </div>
                                        </div>

                                        <div class="form-group">
                                            <label for="to" class="control-label col-sm-2">Subject</label>
                                            <div class="col-sm-10">
                                                <div class="row"><div class="col-sm-12"><input type="text" name="subject" id="subject" class="form-control input-sm" value="" placeholder=""/></div></div>
                                            </div>
                                        </div>

                                        <div class="form-group">
                                            <label for="name" class="control-label col-sm-2">氏名</label>
                                            <div class="col-sm-10">
                                                <div class="row"><div class="col-sm-8"><input type="text" name="name" id="name" class="form-control input-sm" value="" placeholder=""/></div></div>
                                            </div>
                                        </div>

                                        <div class="form-group">
                                            <label class="control-label col-sm-2">項目</label>
                                            <div class="col-sm-10">
                                                <div class="row"><div class="col-sm-12">
                                                    <div class="checkbox">
                                                        <label><input type="checkbox" name="type" value="1"/>資料請求</label> 
                                                        <label><input type="checkbox" name="type" value="2"/>商品に関する苦情</label> 
                                                        <label><input type="checkbox" name="type" value="3"/>その他</label>
                                                    </div>
                                                </div></div>
                                            </div>
                                        </div>
                                        <div class="text-center">
                                            <button type="button" id="search" value="search" class="btn btn-primary bg-gray">検索</button>
                                        </div>
                                    </form>
                                </div>
                            </div>
                        </div>
                        <div class="box-body">
                            <div id="maillist_wrapper" class="dataTables_wrapper form-inline" role="grid">
                                <table id="maillist" class="table table-bordered table-hover dataTable" aria-describedby="maillist_info">
                                    <thead class="bg-purple">
                                        <tr role="row">
                                            <th role="columnheader" tabindex="0" aria-controls="maillist" rowspan="1" colspan="1">To</th>
                                            <th role="columnheader" tabindex="0" aria-controls="maillist" rowspan="1" colspan="1">Subject</th>
                                            <th role="columnheader" tabindex="0" aria-controls="maillist" rowspan="1" colspan="1">氏名</th>
                                            <th role="columnheader" tabindex="0" aria-controls="maillist" rowspan="1" colspan="1">項目</th>
                                        </tr>
                                    </thead>
                                    <tbody role="alert" aria-live="polite" aria-relevant="all">
                                        <tr>
                                            <td>test@sample.com</td>
                                            <td>件名1</td>
                                            <td>田中 太郎</td>
                                            <td>資料請求</td>
                                        </tr>
                                        <tr>
                                            <td>test2@sample.com</td>
                                            <td>件名2</td>
                                            <td>鈴木 花子</td>
                                            <td>商品に関する苦情</td>
                                        </tr>
                                        <tr>
                                            <td>test3@sample.com</td>
                                            <td>件名3</td>
                                            <td>木村 二郎</td>
                                            <td>その他</td>
                                        </tr>
                                    </tbody>
                                </table>
                                <div class="row">
                                    <div class="col-xs-12">
                                        <div class="dataTables_paginate paging_bootstrap">
                                            <ul class="pagination">
                                                <li class="prev disabled"><a href="#">← Previous</a></li>
                                                <li class="active"><a href="#">1</a></li>
                                                <li><a href="#">2</a></li>
                                                <li><a href="#">3</a></li>
                                                <li><a href="#">4</a></li>
                                                <li><a href="#">5</a></li>
                                                <li class="next"><a href="#">Next → </a></li>
                                            </ul>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
        <!-- /.content -->
    </div>
    <!-- /.content-wrapper -->

</div>
<!-- ./wrapper -->

<!-- REQUIRED JS SCRIPTS -->

<div th:replace="common/bottom-js"></div>
<script type="text/javascript">
<!--
$(document).ready(function() {
    $('#to').focus();

    $('#search').bind('click', function(){
        $('#mailSearchForm').submit();
    });
});
-->
</script>
</body>
</html>
  • <html xmlns="http://www.w3.org/1999/xhtml"><html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> へ変更します。
  • <!-- Bootstrap 3.3.2 --> ... <![endif]--><meta th:replace="common/head-cssjs"/> へ変更します。
  • <header class="main-header"> ... </header><div th:replace="common/mainparts :: main-header"></div> へ変更します。
  • <aside class="main-sidebar"> ... </aside><div th:replace="common/mainparts :: main-sidebar (active='mailsearch')"></div> へ変更します。
  • <form id="mailForm" method="post" action="/mailsend/send" class="form-horizontal"><form id="mailSearchForm" method="post" action="/mailsearch" th:action="@{/mailsearch}" class="form-horizontal"> へ変更します。
  • <!-- jQuery 2.1.3 --> ... <script src="/js/app.min.js" type="text/javascript"></script><div th:replace="common/bottom-js"></div> へ変更します。
  • </body> の直前に画面独自の Javascript を記述する <script type="text/javascript"> ... </script> を追加します。

common/head-cssjs.html

    <!-- Bootstrap 3.3.2 -->
    <link href="/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
    <!-- Font Awesome Icons -->
    <link href="/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>
    <!-- Ionicons -->
    <link href="/css/ionicons.min.css" rel="stylesheet" type="text/css"/>
    <!-- Theme style -->
    <link href="/css/AdminLTE.min.css" rel="stylesheet" type="text/css"/>
    <!-- AdminLTE Skins. We have chosen the skin-blue for this starter
          page. However, you can choose any other skin. Make sure you
          apply the skin class to the body tag so the changes take effect.
    -->
    <link href="/css/skins/skin-blue.min.css" rel="stylesheet" type="text/css"/>

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="/js/html5shiv.js"></script>
    <script src="/js/respond.min.js"></script>
    <![endif]-->
  • 各画面の <head> ... </head> 内に共通で定義する css, js の記述のみ残し、それ以外を削除します。

common/mainparts.html

<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8"/>
    <title>ksbysample-webapp-email</title>
    <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'/>
    <!-- Bootstrap 3.3.2 -->
    <link href="/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
    <!-- Font Awesome Icons -->
    <link href="/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>
    <!-- Ionicons -->
    <link href="/css/ionicons.min.css" rel="stylesheet" type="text/css"/>
    <!-- Theme style -->
    <link href="/css/AdminLTE.min.css" rel="stylesheet" type="text/css"/>
    <!-- AdminLTE Skins. We have chosen the skin-blue for this starter
          page. However, you can choose any other skin. Make sure you
          apply the skin class to the body tag so the changes take effect.
    -->
    <link href="/css/skins/skin-blue.min.css" rel="stylesheet" type="text/css"/>

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="/js/html5shiv.js"></script>
    <script src="/js/respond.min.js"></script>
    <![endif]-->
</head>
<body class="skin-blue">
<div class="wrapper">

    <!-- Main Header -->
    <header class="main-header" th:fragment="header">
        <!-- Logo -->
        <a class="logo"><b>ksbysample-email</b></a>

        <!-- Header Navbar -->
        <nav class="navbar navbar-static-top" role="navigation">
            <!-- Sidebar toggle button-->
            <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
                <span class="sr-only">Toggle navigation</span>
            </a>
        </nav>
    </header>

    <!-- Left side column. contains the logo and sidebar -->
    <aside class="main-sidebar" th:fragment="sidebar (active)">
        <!-- sidebar: style can be found in sidebar.less -->
        <section class="sidebar">
            <!-- Sidebar Menu -->
            <ul class="sidebar-menu">
                <!-- Optionally, you can add icons to the links -->
                <li class="treeview active">
                    <a href="#"><span>メール送信機能</span> <i class="fa fa-angle-left pull-right"></i></a>
                    <ul class="treeview-menu">
                        <li th:class="${active == 'mailsend'} ? 'active'"><a href="/mailsend"><i class="fa fa-circle-o"></i>メール送信</a></li>
                        <li th:class="${active == 'mailsearch'} ? 'active'"><a href="/mailsearch"><i class="fa fa-circle-o"></i>送信済メール検索</a></li>
                    </ul>
                </li>
            </ul>
            <!-- /.sidebar-menu -->
        </section>
        <!-- /.sidebar -->
    </aside>

    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">

    </div>
    <!-- /.content-wrapper -->

</div>
<!-- ./wrapper -->

<!-- REQUIRED JS SCRIPTS -->

<!-- jQuery 2.1.3 -->
<script src="/js/jQuery-2.1.3.min.js"></script>
<!-- Bootstrap 3.3.2 JS -->
<script src="/js/bootstrap.min.js" type="text/javascript"></script>
<!-- AdminLTE App -->
<script src="/js/app.min.js" type="text/javascript"></script>
</body>
</html>
  • 共通パーツを定義するファイルとして以下の点を変更しています。
    • 共通パーツにする部分に th:fragment="..." を追加しています。
    • アクティブな画面のメニューを濃い白色の文字色で表示させるために、対象画面のメニューが <li class="active"> になる処理を追加しています。
  • <div class="content-wrapper"> ... </div> の中は全て削除します ( 共通部分のみ定義するファイルのため ) 。
  • <header class="main-header"><header class="main-header" th:fragment="main-header"> に変更します。
  • <aside class="main-sidebar"><aside class="main-sidebar" th:fragment="main-sidebar (active)"> に変更します。
  • <li><a href="#"><i class="fa fa-circle-o"></i>メール送信</a></li><li th:class="${active == 'mailsend'} ? 'active'"><a href="/mailsend"><i class="fa fa-circle-o"></i>メール送信</a></li> へ変更します。
  • <li><a href="#"><i class="fa fa-circle-o"></i>送信済メール検索</a></li><li th:class="${active == 'mailsearch'} ? 'active'"><a href="/mailsearch"><i class="fa fa-circle-o"></i>送信済メール検索</a></li> へ変更します。

common/bottom-js.html

<!-- jQuery 2.1.3 -->
<script src="/js/jQuery-2.1.3.min.js"></script>
<!-- Bootstrap 3.3.2 JS -->
<script src="/js/bootstrap.min.js" type="text/javascript"></script>
<!-- AdminLTE App -->
<script src="/js/app.min.js" type="text/javascript"></script>
  • 各画面の </body> の直前に共通で定義する js の記述のみ残し、それ以外を削除します。

履歴

2015/04/18
初版発行。