読者です 読者をやめる 読者になる 読者になる

かんがるーさんの日記

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

Spring Boot でログイン画面 + 一覧画面 + 登録画面の Webアプリケーションを作る ( その5 )( Controllerクラス+Thymeleafテンプレートファイル作成 )

概要

Spring Boot でログイン画面 + 一覧画面 + 登録画面の Webアプリケーションを作る ( その4 )( HTMLファイル作成2 ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Controller クラスの作成、Thymeleaf テンプレートファイルの作成 ( この時点でひと通り画面遷移が見られるようにします )
  • 1画面作成する毎にコミットして、最後に GitHub へ Pull する時に commit を1つにマージしてから送信してみます。

ソフトウェア一覧

参考にしたサイト

  1. 文字実体参照・数値文字参照
    https://w3g.jp/others/data/letters

手順

画面毎の URL の決定

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

画面 アクション URL
共通 「検索/一覧」メニュークリック /countryList
「登録」メニュークリック /country/input
「ログアウト」メニュークリック /logout
ログイン画面 初期表示 /
「ログイン」ボタンクリック /login
検索/一覧画面 初期表示 /countryList
「検索」ボタンクリック /countryList
登録画面(入力) 初期表示 /country/input
「確認」ボタンクリック /country/confirm
登録画面(確認) 初期表示 /country/confirm
「登録」ボタンクリック /country/update
「戻る」ボタンクリック /country/input
登録画面(完了) 初期表示 /country/complete
「次のデータを登録する」ボタンクリック /country/input
「検索/一覧画面へ」ボタンクリック /countryList
  • 検索/一覧画面は /country/list でもよいかもしれないと思いましたが、今回は検索/一覧画面と登録画面を分けることにしたので、別々のURLにします。

今回の作業用 branch の作成

  1. IntelliJ IDEA のメイン画面のメニューから「VCS」->「VCS Operations Popup...」を選択します。

  2. VCS Operations」メニューが表示されます。「Branches...」メニューを選択します。

  3. 「Git Branches」メニューが表示されます。「New Branch」メニューを選択します。

  4. 「Create New Branch」ダイアログが表示されます。"1.0.x-makecontroller" を入力して「OK」ボタンをクリックします。

ログイン画面の Controller クラス、Thymeleaf テンプレートファイルの作成

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

  2. src/main/resources/templates の下に login.html を作成します。作成後、/static/login.html の内容をまるごとコピー&ペーストします。ペーストはメイン画面のメニューの 「Edit」->「Paste Simple」 で行います ( 通常の Paste だとフォーマットが崩れるためです )。

  3. login.html の内容の一部をリンク先の内容に変更します。

  4. 作成した HTML の内容を確認します。Gradle tasks View から bootRun を実行します。

  5. ブラウザで http://localhost:8080/ にアクセスしてログイン画面が表示されることを確認します。確認後、Ctrl+F2 を押して Tomcat を停止します。

  6. Test クラスを作成します。LoginController.java のエディタで、クラス名にカーソルを移動した後、Alt+Enter を押してメニューを表示し、「Create Test」メニューを選択します。

    f:id:ksby:20150111212052p:plain

  7. 「Create Test」ダイアログが表示されますので、index():String をチェックした後「OK」ボタンをクリックします。

    f:id:ksby:20150111211436p:plain

  8. src/test/java/ksbysample/webapp/basic/web の下に LoginControllerTest.java が新規作成されエディタで開かれますので、リンク先の内容に変更します。

  9. Project View の一番上の階層の ksbysample-webapp-basic を選択した後コンテキストメニューを表示し「Run 'Tests in 'ksbysample...' with Coverage」を選択してテストを実行しますが、現在の設定では IntelliJ IDEA coverage runner の JVM-Dspring.profiles.active=develop の設定が渡されていないためエラーになります。

    f:id:ksby:20150112120820p:plain

  10. IntelliJ IDEA coverage runner 実行時に JVM-Dspring.profiles.active=develop の設定が渡されるようにします。メイン画面のメニューから「Run」->「Edit Configurations...」を選択します。

    f:id:ksby:20150112121018p:plain

  11. 「Run/Debug Configurations」ダイアログが表示されます。画面左側の一覧から「Defaults」->「JUnit」を選択します。

  12. 画面右側に JUnit の設定画面が表示されますので、「VM options」の設定を -ea -Dspring.profiles.active=develop に変更した後「OK」ボタンをクリックします。

    f:id:ksby:20150112121926p:plain

  13. 再度 Project View の一番上の階層の ksbysample-webapp-basic を選択した後コンテキストメニューを表示し「Run 'Tests in 'ksbysample...' with Coverage」を選択してテストを実行すると、Run View に All Tests Passed のメッセージが表示されます。

    f:id:ksby:20150112122141p:plain

  14. Gradle tasks View から build タスクを実行し、BUILD SUCCESSFUL が表示されることも確認します。

  15. commit します。メイン画面のメニューから「VCS」->「Commit Changes...」を選択します。

  16. 「Commit Changes」ダイアログが表示されます。Commit Message を入力後、「Commit」ボタンのドロップダウンメニューから「Commit」を選択します。

    f:id:ksby:20150112123240p:plain

  17. 「Code Analysis」ダイアログが表示されますので、「Review」ボタンをクリックします。

    f:id:ksby:20150111082805p:plain

  18. 画面下部に Messages Code Analysis View が表示され、問題のある箇所が表示されますので、ダブルクリックします。

    f:id:ksby:20150111083126p:plain

  19. LoginController.java が開き問題のある箇所の左側が赤色になっています。該当箇所にマウスカーソルを置くと電球アイコンが表示されますので、それをクリックしてメニューを表示します。今回の場合 Code Analysis の対象外にしたいので、メニューから「Suppress for classes annotated by 'org.springframework.stereotype.Controller'」を選択します。

    f:id:ksby:20150111083424p:plain

  20. 再度メイン画面のメニューから「VCS」->「VCS Operations Popup...」を選択して「VCS Operations」メニューを表示し「Commit Changes...」を選択します。

  21. 「Commit Changes」ダイアログが表示されますので、「Commit」ボタンのドロップダウンメニューから「Commit」を選択します。

  22. 今度は「Code Analysis」ダイアログは表示されずに commit が完了します。

    f:id:ksby:20150111084356p:plain

検索/一覧画面の Controller クラス、Thymeleaf テンプレートファイルの作成

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

  2. src/main/resources/templates の下に countryList.html を作成します。作成後、/static/countrylist.html の内容をまるごとコピー&ペーストします。

  3. countryList.html の内容の一部をリンク先のその1の内容に変更します。

  4. 作成した HTML の内容を確認します。Gradle tasks View から bootRun を実行します。

  5. ブラウザで http://localhost:8080/countryList にアクセスして検索/一覧画面が表示されることを確認します。確認後、Ctrl+F2 を押して Tomcat を停止します。

  6. Test クラスを作成します。CountryListController.java のエディタで、クラス名にカーソルを移動した後、Alt+Enter を押してメニューを表示し、「Create Test」メニューを選択します。

  7. 「Create Test」ダイアログが表示されますので、index():String をチェックした後「OK」ボタンをクリックします。

  8. src/test/java/ksbysample/webapp/basic/web の下に CountryListControllerTest.java が新規作成されエディタで開かれますので、リンク先の内容に変更します。

  9. Project View の一番上の階層の ksbysample-webapp-basic を選択した後コンテキストメニューを表示し「Run 'Tests in 'ksbysample...' with Coverage」を選択してテストを実行しますが、org.xml.sax.SAXParseException; lineNumber: 113; columnNumber: 40; エンティティ"laquo"が参照されていますが、宣言されていません。 というエラーメッセージが表示されてエラーになります。

    原因は基本仕様にない実体参照は使えないからのようです。««へ、»» ヘ修正して再度テストを実行し、Run View に All Tests Passed のメッセージが表示されることを確認します。

  10. Gradle tasks View から build タスクを実行し、BUILD SUCCESSFUL が表示されることも確認します。

  11. commit します。メイン画面のメニューから「VCS」->「Commit Changes...」を選択します。

  12. 「Commit Changes」ダイアログが表示されます。Commit Message を入力後、「Commit」ボタンのドロップダウンメニューから「Commit」を選択します。

    f:id:ksby:20150112234716p:plain

登録画面の Controller クラス、Thymeleaf テンプレートファイルの作成

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

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

  3. src/main/resources/templates/country の下に input.html を作成します。作成後、/static/countryInput.html の内容をまるごとコピー&ペーストします。

  4. input.html の内容の一部をリンク先のその1~3の内容に変更します。

  5. src/main/resources/templates/country の下に confirm.html を作成します。作成後、/static/countryConfirm.html の内容をまるごとコピー&ペーストします。

  6. confirm.html の内容の一部をリンク先のその1~3の内容に変更します。

  7. src/main/resources/templates/country の下に complete.html を作成します。作成後、/static/countryComplete.html の内容をまるごとコピー&ペーストします。

  8. complete.html の内容の一部をリンク先のその1~2の内容に変更します。

  9. 作成した HTML の内容を確認します。Gradle tasks View から bootRun を実行します。ブラウザで http://localhost:8080/country/input にアクセスしてから各種ボタンをクリックし、登録画面 ( 入力→確認→完了 ) が表示されることを確認します。確認後、Ctrl+F2 を押して Tomcat を停止します。

  10. Test クラスを作成します。CountryController.java のエディタで、クラス名にカーソルを移動した後、Alt+Enter を押してメニューを表示し、「Create Test」メニューを選択します。

  11. 「Create Test」ダイアログが表示されますので、Member に表示されるメソッドを全てチェックした後「OK」ボタンをクリックします。

    f:id:ksby:20150114004930p:plain

  12. src/test/java/ksbysample/webapp/basic/web の下に CountryControllerTest.java が新規作成されエディタで開かれますので、リンク先の内容に変更します。

  13. Project View の一番上の階層の ksbysample-webapp-basic を選択した後コンテキストメニューを表示し「Run 'Tests in 'ksbysample...' with Coverage」を選択してテストを実行し、Run View に All Tests Passed のメッセージが表示されることを確認します。

  14. Gradle tasks View から build タスクを実行し、BUILD SUCCESSFUL が表示されることも確認します。

  15. commit します。メイン画面のメニューから「VCS」->「Commit Changes...」を選択します。

  16. 「Commit Changes」ダイアログが表示されます。Commit Message を入力後、「Commit」ボタンのドロップダウンメニューから「Commit」を選択します。

    f:id:ksby:20150114012815p:plain

Thymeleaf テンプレートファイルのヘッダの共通化

HTMLの共通部分を別ファイルに切り出します。

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

  2. src/main/resources/templates/common の下に header.html を作成し、リンク先のその1の内容に変更します。

  3. src/main/resources/templates の下の countryList.html の body タグの直下にある <nav class="navvar navbar-inverse navbar-fixed-top" role="navigation"></nav>リンク先のその2の内容に変更します。

  4. 画面の表示内容を確認します。Gradle tasks View から bootRun を実行して、ブラウザで http://localhost:8080/countryList にアクセスします。以下の画像のようにヘッダが表示され、かつ「検索/一覧」の文字がハイライトで表示されていることが確認できます。Tomcat はこのまま起動しておきます。

    f:id:ksby:20150114002052p:plain

  5. src/main/resources/templates/country の下の input.html, confirm.html, complete.html の body タグの直下にある <nav class="navvar navbar-inverse navbar-fixed-top" role="navigation"></nav>リンク先の内容に変更します。

  6. 画面の表示内容を確認します。ブラウザで http://localhost:8080/country/input にアクセスします。以下の画像のようにヘッダが表示され、かつ「登録」の文字がハイライトで表示されていることが確認できます。確認後、Ctrl+F2 を押して Tomcat を停止します。

    f:id:ksby:20150114004126p:plain

  7. commit します。メイン画面のメニューから「VCS」->「Commit Changes...」を選択します。

  8. 「Commit Changes」ダイアログが表示されます。Commit Message を入力後、「Commit」ボタンのドロップダウンメニューから「Commit」を選択します。

    f:id:ksby:20150114013509p:plain

  9. 「Code Analysis」ダイアログが表示されますので、「Review」ボタンをクリックします。

  10. 画面下部に Messages Code Analysis View が表示され、問題のある箇所が表示されますので、ダブルクリックします。

    f:id:ksby:20150114073709p:plain

  11. th の Namespace の宣言がなくてエラーになっているので、HTMLを修正します。まずは header.html をリンク先のその2の内容に変更します。

  12. 次に http://www.thymeleaf.org の上にカーソルを移動した後 Alt+Enter を押下してメニューを表示した後、「Ignore External Resource」を選択します。

    f:id:ksby:20150115010947p:plain

  13. 登録されている場所を確認します。メイン画面のメニューから「File」->「Settings...」を選択します。

  14. 「Settings」ダイアログが表示されます。画面左側の「Languages & Frameworks」->「Schemes and DTDs」を選択すると、画面右側の「Ignored Schemes and DTDs」に登録された内容が表示されています。「OK」ボタンをクリックしてダイアログを閉じます。

    f:id:ksby:20150115011248p:plain

  15. 再度 commit します。メイン画面のメニューから「VCS」->「Commit Changes...」を選択して「Commit Changes」ダイアログが表示し、「Commit」ボタンのドロップダウンメニューから「Commit」を選択します。

  16. 「Code Analysis」ダイアログが表示されますので「Review」ボタンをクリックします。今度は画面下部の Messages Code Analysis View の header.html に表示されたいた Namespace 'th' is not bound のエラーが消えています。Messages Code Analysis View に表示されている他の htmlファイルもリンク先のその2の内容に変更します。

  17. 画面下部の Messages Code Analysis View には Attribute th:... is not allowed here という Warning が表示されていますので、次にこれを解消します。まずこの Warning をダブルクリックしてソースの該当箇所に移動します。

  18. 移動すると電球のアイコンが表示されていますので、クリックしてメニューを表示後「Add th:... to custom html attributes」を選択します。これを Warning が出ている attribute の種類分実行します。

    f:id:ksby:20150115012248p:plain

  19. 再度 commit します。メイン画面のメニューから「VCS」->「Commit Changes...」を選択して「Commit Changes」ダイアログが表示し、「Commit」ボタンのドロップダウンメニューから「Commit」を選択します。今度は commit が正常に完了します。

    f:id:ksby:20150115012558p:plain

  20. ここまでで Project のディレクトリ・ファイルは以下の構成になっています。

    f:id:ksby:20150115013048p:plain

GitHub への push

複数 commit しているので1つにまとめて、commit メッセージも修正してから push します。commit を1つにまとめて commit メッセージを修正する作業はコマンドプロンプトから git コマンドを直接実行して行います ( IntelliJ IDEA の Terminal では日本語がうまく表示されなかったためコマンドプロンプトで実行しました )。

  1. まず4回の commit を1つにまとめます。コマンドプロンプトを起動し、以下のコマンドを実行します。

    > cd /d C:\project-springboot\ksbysample-webapp-basic
    > git rebase -i HEAD~4

  2. 以下の内容が表示されます。ここから先は vim の操作と同じです。

    f:id:ksby:20150115025916p:plain

  3. 最初の行のみ pick のままとし、残りの3行の pick → fixup に変更します。

    f:id:ksby:20150115030235p:plain

  4. 保存&終了します。以下の画像のような内容が出力されて commit が1つにまとめられます。

    f:id:ksby:20150115030415p:plain

  5. 次に commit メッセージを修正します。コマンドプロンプトで以下のコマンドを実行します。

    > git commit --amend

  6. 以下の内容が表示されます。

    f:id:ksby:20150115032415p:plain

  7. commit メッセージを変更します。

    f:id:ksby:20150115032636p:plain

  8. 保存&終了します。以下の画像のような内容が出力されます。

    f:id:ksby:20150115032817p:plain

  9. IntelliJ IDEA のメイン画面のメニューから「VCS」->「VCS Operations Popup...」を選択して「VCS Operations」メニューを表示した後、「Push...」を選択します。

  10. 「Push Commits」ダイアログが表示されます。commit が1つにまとまっていることが確認できます。「Push」ボタンをクリックして GitHub にアップロードします。

    f:id:ksby:20150115033207p:plain

GitHub で Pull Request を送信、1.0.x_makecontroller → 1.0.x へ merge

  1. https://github.com/ksby/ksbysample-webapp-basic にアクセスします。

  2. 画面上部に以下の画像と同じ内容が表示されていますので、「Compare & pull request」ボタンをクリックします。

    f:id:ksby:20150115033903p:plain

  3. pull request の作成画面が表示されますので、左上の base の branch を 1.0.x に変更し、comment を入力した後、「Create pull request」ボタンをクリックします。

    f:id:ksby:20150115034155p:plain

  4. 今回は GitHub 上で merge します。https://github.com/ksby/ksbysample-webapp-basic/pulls にアクセスします。登録した pull request が表示されていますのでクリックします。

  5. pull request の画面が表示されますので「Files changed」タブからソースの内容を確認した後、「Merge pull request」ボタンをクリックします。

    f:id:ksby:20150115035104p:plain

  6. 以下の画面が表示されますので、「Confirm merge」ボタンをクリックします。

    f:id:ksby:20150115035211p:plain

  7. 以下の画面が表示されますので、「Delete branch」ボタンをクリックします。

    f:id:ksby:20150115035425p:plain

IntellIJ IDEA で 1.0.x branch へ変更&Pull、1.0.x-makecontroller branch の削除

  1. IntelliJ IDEA のメイン画面のメニューから「VCS」->「VCS Operations Popup...」を選択して「VCS Operations」メニューを表示した後、「Branches...」を選択します。

  2. 「Git Branches」メニューが表示されます。「1.0.x -> origin/1.0.x」->「Checkout」を選択して branch を 1.0.x に切り替えます。

    f:id:ksby:20150115035950p:plain

  3. IntelliJ IDEA のメイン画面のメニューから「VCS」->「Update Project...」を選択します。

    f:id:ksby:20150115040134p:plain

  4. 「Update Project」ダイアログが表示されますので、「OK」ボタンをクリックします。GitHub 上で merge したファイルがダウンロードされます。

  5. IntelliJ IDEA のメイン画面のメニューから「VCS」->「VCS Operations Popup...」を選択して「VCS Operations」メニューを表示した後、「Branches...」を選択します。「Git Branches」メニューが表示されたら、「1.0.x-makecontroller」->「Delete」を選択してローカルの 1.0.x-makecontroller branch を削除します。

    f:id:ksby:20150115040520p:plain

ソースコード

LoginController.java

package ksbysample.webapp.basic.web;

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

@Controller
public class LoginController {

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

}

login.html

                <form role="form" action="/countryList" method="post" id="login-form" autocomplete="off">
  • action の URL を /countryList に変更します。

LoginControllerTest.java

package ksbysample.webapp.basic.web;

import ksbysample.webapp.basic.Application;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class LoginControllerTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setUp() {
        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void testIndex() throws Exception {
        this.mvc.perform(get("/")).andExpect(status().isOk())
                .andExpect(content().contentType("text/html;charset=UTF-8"))
                .andExpect(view().name("login"));
    }

}

CountryListController.java

package ksbysample.webapp.basic.web;

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

@Controller
@RequestMapping("/countryList")
public class CountryListController {

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

countryList.html

■その1

        <div class="panel panel-default">
            <div class="panel-heading">
                <div class="panel-title">検索条件</div>
            </div>
            <div class="panel-body">
                <form method="post" action="/countryList" class="form-horizontal">
  • action の URL を /countryList に変更します。

■その2

    <div id="header" th:include="common/header :: header (active='countryList')"></div>

CountryListControllerTest.java

package ksbysample.webapp.basic.web;

import ksbysample.webapp.basic.Application;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class CountryListControllerTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setUp() {
        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void testIndex() throws Exception {
        this.mvc.perform(get("/countryList")).andExpect(status().isOk())
                .andExpect(content().contentType("text/html;charset=UTF-8"))
                .andExpect(view().name("countryList"))
                .andExpect(xpath("/html/head/title").string("検索/一覧画面"));
    }

}

CountryController.java

package ksbysample.webapp.basic.web;

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

@Controller
@RequestMapping("/country")
public class CountryController {

    @RequestMapping("/input")
    public String input() {
        return "country/input";
    }

    @RequestMapping("/confirm")
    public String confirm() {
        return "country/confirm";
    }

    @RequestMapping("/update")
    public String update() {
        return "redirect:/country/complete";
    }

    @RequestMapping("/complete")
    public String complete() {
        return "country/complete";
    }

}

input.html

■その1

                <form id="countryForm" method="post" action="/country/confirm" class="form-horizontal">
  • id="countryForm" を追加し、action の URL を /country/confirm に変更します。

■その2

                        <button type="button" id="js-confirm" value="confirm" class="btn btn-primary">確認</button>
  • id="js-confirm" を追加します。

■その3

    <script type="text/javascript">
    <!--
    $(document).ready(function() {
        $('#code').focus();

        $('#js-confirm').bind('click', function(){
            $('#countryForm').submit();
        });
    });
    -->
    </script>
  • $('#js-confirm').bind('click', ... の処理を追加します。

confirm.html

■その1

                <form id="countryForm" method="post" action="/country/update" class="form-horizontal">
  • id="countryForm" を追加し、action の URL を /country/update に変更します。

■その2

                        <button type="button" id="js-update" value="update" class="btn btn-primary">登録</button>
                        <button type="button" id="js-back" value="back" class="btn btn-default">戻る</button>
  • id="js-update"id="js-back" を追加します。

■その3

    <script type="text/javascript">
    <!--
    $(document).ready(function() {
        $('#js-update').bind('click', function(){
            $('#countryForm').submit();
        });

        $('#js-back').bind('click', function(){
           $('#countryForm').attr('action', '/country/input');
            $('#countryForm').submit();
        });
    });
    -->
    </script>
  • $(document).ready(function() { ... の処理を追加します。

complete.html

■その1

                <button type="button" id="js-input" value="input" class="btn btn-primary">次のデータを登録する</button>
                <button type="button" id="js-toCountryList" value="toCountryList" class="btn btn-default">検索/一覧画面へ</button>
  • id="js-input"id="js-toCountryList" を追加します。

■その2

    <script type="text/javascript">
    <!--
    $(document).ready(function() {
        $('#js-input').bind('click', function(){
            location.href = '/country/input';
        });

        $('#js-toCountryList').bind('click', function(){
            location.href = '/countryList';
        });
    });
    -->
    </script>
  • $(document).ready(function() { ... の処理を追加します。

CountryControllerTest.java

package ksbysample.webapp.basic.web;

import ksbysample.webapp.basic.Application;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class CountryControllerTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setUp() {
        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void testInput() throws Exception {
        this.mvc.perform(get("/country/input")).andExpect(status().isOk())
                .andExpect(content().contentType("text/html;charset=UTF-8"))
                .andExpect(view().name("country/input"))
                .andExpect(xpath("/html/head/title").string("Countryデータ登録画面(入力)"));
    }

    @Test
    public void testConfirm() throws Exception {
        this.mvc.perform(get("/country/confirm")).andExpect(status().isOk())
                .andExpect(content().contentType("text/html;charset=UTF-8"))
                .andExpect(view().name("country/confirm"))
                .andExpect(xpath("/html/head/title").string("Countryデータ登録画面(確認)"));
    }

    @Test
    public void testUpdate() throws Exception {
        this.mvc.perform(get("/country/update")).andExpect(status().isFound())
                .andExpect(redirectedUrl("/country/complete"));
    }

    @Test
    public void testComplete() throws Exception {
        this.mvc.perform(get("/country/complete")).andExpect(status().isOk())
                .andExpect(content().contentType("text/html;charset=UTF-8"))
                .andExpect(view().name("country/complete"))
                .andExpect(xpath("/html/head/title").string("Countryデータ登録画面(完了)"));
    }

}

header.html

■その1

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>

    <title>ヘッダー</title>

    <!-- Bootstrap core CSS -->
    <link href="/css/bootstrap.min.css" rel="stylesheet"/>

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="/js/html5shiv.min.js"></script>
    <script src="/js/respond.min.js"></script>
    <![endif]-->

    <!-- Custom styles for this template -->
    <style>
    <!--
    body {
        padding-top: 50px;
    }
    .navbar-brand {
        font-size: 24px;
    }
    .form-group {
        margin-bottom: 5px;
    }
    -->
    </style>
</head>

<body>

    <div th:fragment="header (active)">
        <nav class="navvar navbar-inverse navbar-fixed-top" role="navigation">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                        <span class="sr-only">ナビゲーションボタン</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <div class="navbar-brand">WebApp - Basic</div>
                </div>
                <div id="navbar" class="collapse navbar-collapse">
                    <ul class="nav navbar-nav  navbar-left">
                        <li th:class="${active == 'countryList'} ? 'active'"><a href="/countryList"><span class="glyphicon glyphicon-search"></span> 検索/一覧</a></li>
                        <li th:class="${active == 'countryInput'} ? 'active'"><a href="/country/input"><span class="glyphicon glyphicon-pencil"></span> 登録</a></li>
                    </ul>
                    <ul class="nav navbar-nav navbar-right">
                        <li><a href="/logout"><span class="glyphicon glyphicon-log-out"></span> ログアウト</a></li>
                    </ul>
                </div>
            </div>
        </nav>
    </div>

</body>
</html>

■その2

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
  • 先頭の2行 <!DOCTYPE html><html lang="ja"> を上記の内容に変更します。

input/confirm/complete.html

    <div id="header" th:include="common/header :: header (active='countryInput')"></div>

履歴

2015/01/15
初版発行。
2015/01/18
th:include="/common/headerth:include="common/headerへ修正(jarファイルにした時にエラーが出たため)。