fragmentを利用したページにナビゲーションを追加
layout.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>layout.html</title>
<style type="text/css">
header {
background: #f0f0f0;
text-align: center;
padding: 50px;
}
footer {
background: #e0e0e0;
text-align: center;
}
</style>
</head>
<body>
<header th:include="header :: header">
仮のヘッダーです
</header>
<nav>
<ul>
<li><a href="/fragment">fragment</a></li>
<li><a href="/mac">mac</a></li>
<li><a href="/windows">windows</a></li>
<li><a href="/linux">linux</a></li>
</ul>
</nav>
<section th:include="${template} :: ${fragment}">
<h1>layout</h1>
<p>本文です。</p>
</section>
<footer th:include="footer :: footer">
仮のフッターです
</footer>
</body>
</html>
switchで分岐
fragmentをそのまま利用して実装してみる。
テンプレート month.html を用意する。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>季節</title>
</head>
<body>
<div th:fragment="month">
<h1>季節</h1>
<p th:text="${fragment}"></p>
<div th:switch="${season}">
<p th:case="0" th:text="|${month}月 - Winter|"></p>
<p th:case="1" th:text="|${month}月 - Spring|"></p>
<p th:case="2" th:text="|${month}月 - Summer|"></p>
<p th:case="3" th:text="|${month}月 - Autumn|"></p>
</div>
</div>
</body>
</html>
FragmentController.java に /month/{month} のマッピングを追加する。
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class FragmentController {
@RequestMapping("/fragment")
public ModelAndView fragment(ModelAndView mav) {
mav.addObject("template", "content");
mav.addObject("fragment", "body1");
mav.setViewName("layout");
return mav;
}
@RequestMapping("/mac")
public ModelAndView mac(ModelAndView mav) {
mav.addObject("template", "content");
mav.addObject("fragment", "mac");
mav.setViewName("layout");
return mav;
}
@RequestMapping("/windows")
public ModelAndView windows(ModelAndView mav) {
mav.addObject("template", "windows");
mav.addObject("fragment", "windows");
mav.setViewName("layout");
return mav;
}
@RequestMapping("/linux")
public ModelAndView linux(ModelAndView mav) {
mav.addObject("template", "linux");
mav.addObject("fragment", "linux");
mav.setViewName("layout");
return mav;
}
@RequestMapping("/month/{month}")
public ModelAndView month(@PathVariable int month, ModelAndView mav) {
mav.addObject("template", "month");
mav.addObject("fragment", "month");
mav.addObject("month", month);
mav.addObject("season", 0);
mav.setViewName("layout");
return mav;
}
}
季節の判定をするために、テスト駆動開発をするのがよさそうなのでやってみる。
FragmentControllerのコードで季節を判定する部分をメソッドにする。
@RequestMapping("/month/{month}")
public ModelAndView month(@PathVariable int month, ModelAndView mav) {
mav.addObject("template", "month");
mav.addObject("fragment", "month");
mav.addObject("month", month);
int season = getSeason(month);
mav.addObject("season", season);
mav.setViewName("layout");
return mav;
}
まず、FragmentControllerで季節を判定するメソッドを作成する。privateだとテストから見えなくなるので、アクセス制限はパッケージプライベートにしておく。
int getSeason() {
return 0;
}
FragmentController.java を右クリックして[新規]-[その他]を選択。
フィルターに「ju」と入力して「JUnitテストケース」を選択してテストケースを作成する。
package com.example.demo;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class FragmentControllerTest {
@Test
void testGetSeason() {
FragmentController fc = new FragmentController();
int season = fc.getSeason(1);
assertEquals(0, season);
}
}
1月から12月までのテストを書く。
package com.example.demo;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class FragmentControllerTest {
@Test
void testGetSeason() {
FragmentController fc = new FragmentController();
int season = fc.getSeason(1);
assertEquals(0, season);
assertEquals(0, fc.getSeason(2));
assertEquals(1, fc.getSeason(3));
assertEquals(1, fc.getSeason(4));
assertEquals(1, fc.getSeason(5));
assertEquals(2, fc.getSeason(6));
assertEquals(2, fc.getSeason(7));
assertEquals(2, fc.getSeason(8));
assertEquals(3, fc.getSeason(9));
assertEquals(3, fc.getSeason(10));
assertEquals(3, fc.getSeason(11));
assertEquals(0, fc.getSeason(12));
}
}
Spring Bootアプリケーションを終了させる方法
「コンソール」タブの「選択されたコンソールの表示」ボタンの右の「▼」をクリックしてXXXApplicationを選択し、■をクリックする。
コマンドプロンプトから java.exe を終了させる方法
C:¥User¥hoge> taskkill /im java.exe
正しく季節を返せるように getSeason() を実装する。
int getSeason(int month) {
if (month < 3 || month == 12) return 0;
if (month < 6) return 1;
if (month < 9) return 2;
return 3;
}
次は季節の一覧をループで表示する /seasons ページを作成する。
まずコントローラに新しいマッピングを追加する。
@RequestMapping("/seasons")
public ModelAndView seasons(ModelAndView mav) {
mav.addObject("template", "seasons");
mav.addObject("fragment", "seasons");
mav.setViewName("layout");
return mav;
}
templates フォルダに seasons.html を作成する。(linux.htmlをseasons.htmlの名前でコピー)
fragmentの名前を「seasons」に変更してSpring Bootを再起動すればアクセスできるようになる。
コントローラで1月から12月までの文字を配列で作成して、テンプレートにわたすようにする。
@RequestMapping("/seasons")
public ModelAndView seasons(ModelAndView mav) {
mav.addObject("template", "seasons");
mav.addObject("fragment", "seasons");
String[] s = new String[12];
for (int i = 1; i <=12; i++) {
s[i - 1] = i + "月";
}
mav.addObject("seasons", s);
mav.setViewName("layout");
return mav;
}
seasons.htmlでは、渡されたString配列でループして1月から12月を表示する。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>linux.html</title>
</head>
<body>
<div th:fragment="seasons">
<h1>季節</h1>
<div th:each="s:${seasons}">
<p th:text="${s}"></p>
</div>
<p th:text="${fragment}"></p>
</div>
</body>
</html>
「○月は春です。」のような表示を12ヶ月分できるように修正する。
@RequestMapping("/seasons")
public ModelAndView seasons(ModelAndView mav) {
mav.addObject("template", "seasons");
mav.addObject("fragment", "seasons");
String[] s = new String[12];
for (int i = 1; i <=12; i++) {
s[i - 1] = i + "月は" + getSeasonName(i) + "です。";
}
mav.addObject("seasons", s);
mav.setViewName("layout");
return mav;
}
String getSeasonName(int month) {
int season = getSeason(month);
if (season == 0) return "冬";
if (season == 1) return "春";
if (season == 2) return "夏";
return "秋";
}