かんがるーさんの日記

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

Spring Boot 1.3.x の Web アプリを 1.4.x へバージョンアップする ( 番外編 )( Thymeleaf 3 へのバージョンアップを試してみる )

概要

記事一覧はこちらです。

Spring Boot 1.4 Release Notes に Thymeleaf 3 の記述がありましたので、Thymeleaf 3 へのバージョンアップを試してみます。

今回は試してみるだけでコミットはしません。

参照したサイト・書籍

  1. Spring Boot Reference Guide - 74.9 Use Thymeleaf 3
    http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-use-thymeleaf-3

  2. Thymeleaf 3 ten-minute migration guide
    http://www.thymeleaf.org/doc/articles/thymeleaf3migration.html

  3. Spring Boot 1.4でThymeleaf 3.0系を使うための設定方法
    http://qiita.com/kazuki43zoo/items/da64a68b9805e512cdc9

  4. Spring Boot 1.4+Thymeleaf 3.0でSpELコンパイラを有効にしてパフォーマンスを向上させよう!!
    http://qiita.com/kazuki43zoo/items/f367845d50589281ed46#_reference-bb5b2b46ee255b058fed

目次

  1. Thymeleaf の定義がある BOM ファイルを探してみる
  2. build.gradle を変更する
  3. clean タスク → Rebuild Project → build タスクを実行してみる
  4. bootRun で起動してみる
  5. 動作確認
  6. Thymeleaf 2 でエラーになったことを Thymeleaf 3 ではエラーにならないか試してみる
  7. 次回は。。。

手順

Thymeleaf の定義がある BOM を探してみる

最初に Spring IO Platform の Athens-SR5 の BOM を見てみます。https://repo1.maven.org/maven2/io/spring/platform/platform-bom/Athens-SR5/platform-bom-Athens-SR5.pom を見ると、その中には “Thymeleaf” に関する定義はありませんでした。

次に Athens-SR5 の BOM の先頭に記述されている spring-boot-starter-parent の BOM を見ます。https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-starter-parent/1.4.6.RELEASE/spring-boot-starter-parent-1.4.6.RELEASE.pom を見ると、この中にも “Thymeleaf” に関する定義はありませんでした。

次に spring-boot-starter-parent の BOM の先頭に記述されている spring-boot-dependencies の BOM を見ます。https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/1.4.6.RELEASE/spring-boot-dependencies-1.4.6.RELEASE.pom を見ると、以下の “Thymeleaf” に関する定義が記述されていました。

<properties>
  ..........
  <thymeleaf.version>2.1.5.RELEASE</thymeleaf.version>
  <thymeleaf-extras-springsecurity4.version>2.1.3.RELEASE</thymeleaf-extras-springsecurity4.version>
  <thymeleaf-extras-conditionalcomments.version>2.1.2.RELEASE</thymeleaf-extras-conditionalcomments.version>
  <thymeleaf-layout-dialect.version>1.4.0</thymeleaf-layout-dialect.version>
  <thymeleaf-extras-data-attribute.version>1.3</thymeleaf-extras-data-attribute.version>
  <thymeleaf-extras-java8time.version>2.1.0.RELEASE</thymeleaf-extras-java8time.version>
  ..........
</properties>
..........
<dependencyManagement>
  <dependencies>
    ..........
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
      <version>1.4.6.RELEASE</version>
    </dependency>
    ..........
    <dependency>
      <groupId>com.github.mxab.thymeleaf.extras</groupId>
      <artifactId>thymeleaf-extras-data-attribute</artifactId>
      <version>${thymeleaf-extras-data-attribute.version}</version>
    </dependency>
    ..........
    <dependency>
      <groupId>nz.net.ultraq.thymeleaf</groupId>
      <artifactId>thymeleaf-layout-dialect</artifactId>
      <version>${thymeleaf-layout-dialect.version}</version>
    </dependency>
    ..........
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf</artifactId>
      <version>${thymeleaf.version}</version>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf-spring4</artifactId>
      <version>${thymeleaf.version}</version>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf.extras</groupId>
      <artifactId>thymeleaf-extras-conditionalcomments</artifactId>
      <version>${thymeleaf-extras-conditionalcomments.version}</version>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf.extras</groupId>
      <artifactId>thymeleaf-extras-java8time</artifactId>
      <version>${thymeleaf-extras-java8time.version}</version>
    </dependency>
    <dependency>
      <groupId>org.thymeleaf.extras</groupId>
      <artifactId>thymeleaf-extras-springsecurity4</artifactId>
      <version>${thymeleaf-extras-springsecurity4.version}</version>
    </dependency>
    ..........
  </dependencies>
</dependencyManagement>

以下の値を設定すればよさそうです。

  • thymeleaf.version
  • thymeleaf-extras-springsecurity4.version
  • thymeleaf-extras-conditionalcomments.version
  • thymeleaf-layout-dialect.version
  • thymeleaf-extras-data-attribute.version
  • thymeleaf-extras-java8time.version

build.gradle を変更する

jcenter, mavenCentral で Thymeleaf の各ライブラリのバージョンを確認した後、build.gradle の dependencyManagement の記述を以下のように変更します。

dependencyManagement {
    imports {
        mavenBom("io.spring.platform:platform-bom:Athens-SR5") {
            bomProperty 'guava.version', '21.0'
            bomProperty 'thymeleaf.version', '3.0.6.RELEASE'
            bomProperty 'thymeleaf-extras-springsecurity4.version', '3.0.2.RELEASE'
            bomProperty 'thymeleaf-layout-dialect.version', '2.2.1'
            bomProperty 'thymeleaf-extras-java8time.version', '3.0.0.RELEASE'
        }
    }
}
  • 以下の記述を追加します。
    • bomProperty 'thymeleaf.version', '3.0.6.RELEASE'
    • bomProperty 'thymeleaf-extras-springsecurity4.version', '3.0.2.RELEASE'
    • bomProperty 'thymeleaf-layout-dialect.version', '2.2.1'
    • bomProperty 'thymeleaf-extras-java8time.version', '3.0.0.RELEASE'

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

Project Tool Window の External Libraries を見ると、指定したバージョンのライブラリがダウンロードされて依存関係にセットされていることが確認できます。

f:id:ksby:20170510012521p:plain f:id:ksby:20170510012652p:plain

clean タスク → Rebuild Project → build タスクを実行してみる

clean タスク → Rebuild Project → build タスクを実行してみると、何のエラーも出ず “BUILD SUCCESSFUL” の文字が出力されました。

f:id:ksby:20170510013223p:plain

Project Tool Window で src/test を選択した後、コンテキストメニューを表示して「Run ‘All Tests’ with Coverage」を選択してテストを実行しても、テストが全て成功することが確認できます。

f:id:ksby:20170510013541p:plain

bootRun で起動してみる

bootRun で Tomcat を起動してみるとエラーは出ずに “Started Application in …” のログが出力されました。

f:id:ksby:20170510013830p:plain

が、途中で 2017-05-10 01:36:50.476 WARN 9576 --- [ restartedMain] org.thymeleaf.templatemode.TemplateMode : [THYMELEAF][restartedMain] Template Mode 'HTML5' is deprecated. Using Template Mode 'HTML' instead. というログも出力されていました。

Spring Boot Reference Guide の 74.9 Use Thymeleaf 3 に warning message を避けたければ spring.thymeleaf.modeHTML を設定するよう記述されていましたので、この設定を反映します。

application.properties を以下のように変更します。

spring.freemarker.cache=true
spring.freemarker.settings.number_format=computer
spring.freemarker.charset=UTF-8
spring.freemarker.enabled=false
spring.freemarker.prefer-file-system-access=false

spring.thymeleaf.mode=HTML

valueshelper.classpath.prefix=
  • spring.thymeleaf.mode=HTML を追加します。

ただし IntelliJ IDEA で spring.thymeleaf.mode に設定可能な値の候補一覧を表示させると HTML は出てきません。

f:id:ksby:20170507192532p:plain

設定した後も HTML は赤字で表示されます。

f:id:ksby:20170507192654p:plain

設定はされているはずなので、bootRun で Tomcat を起動してみると、今度は WARN ログは出ずに “Started Application in …” のログが出力されました。

動作確認

jar ファイルを作成して Spring Boot 1.3.x の Web アプリを 1.4.x へバージョンアップする ( その26 )( jar ファイルを作成して動作確認する2 ) に書いた手順で動作確認します。

結果は以下の通りです。

  • 動作確認は全て正常に動作しました。ksbysample-webapp-lending.log にもエラーは出力されていません。
  • 画面は以前と全く変わらず表示されました。
  • Thymeleaf 3 は 2 よりパフォーマンスアップしているという話でしたが、このアプリの画面だと全然分かりませんでした。。。

Thymeleaf 2 でエラーになったことを Thymeleaf 3 ではエラーにならないか試してみる

Thymeleaf を使用する上で手間だと思っていたのは以下の2点です。

  • HTML5 では閉じタグは必須ではないが、閉じタグを付けないとエラーになる。例えば <meta charset="UTF-8"> は末尾を /> とスラッシュを付けて <meta charset="UTF-8"/> としないとダメ。<meta charset="UTF-8"> の場合、org.xml.sax.SAXParseException: 要素タイプ"meta"は、対応する終了タグ"</meta>"で終了する必要があります。 のログが出力される。
  • 属性は必ず ="..." を付ける必要がある。例えば xxx 属性を追加する場合、<div class="content-wrapper" xxx> はエラーになり、<div class="content-wrapper" xxx=""> のようにする必要がある。<div class="content-wrapper" xxx> の場合、org.xml.sax.SAXParseException: 要素タイプ"div"に関連付けられている属性名"xxx"の後には、' = '文字が必要です。 のログが出力される。

src/main/resources/templates/login.html で試してみます。以下の点を変更します。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>ログイン画面</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
    <!-- Bootstrap 3.3.4 -->
    <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. Choose a skin from the css/skins
         folder instead of downloading all of them to reduce the load. -->
    <link href="/css/skins/_all-skins.min.css" rel="stylesheet" type="text/css">

    ..........
</head>

<!-- ADD THE CLASS layout-top-nav TO REMOVE THE SIDEBAR. -->
<body class="skin-blue layout-top-nav">
<div class="wrapper">

    <!-- Full Width Column -->
    <div class="content-wrapper">
        <div class="container">
            <!-- Main content -->
            <section class="content">
  • <head>...</head> 内の meta, link タグの末尾の / を削除します。
  • <div class="content-wrapper"> に xxx 属性を追加して <div class="content-wrapper" xxx> にします。

bootRun で Tomcat を起動した後、http://localhost:8080/ にアクセスすると、ログイン画面が表示されました。

f:id:ksby:20170507220634p:plain

また他に気付いたこととして <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"><html> でも画面は表示されるのですが(これは Thymeleaf 2 でも表示されます)、<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> にしないと IntelliJ IDEA で th: 属性の補完が効かなくなりますので、これはこのままにします。

次回は。。。

Thymeleaf 3 ten-minute migration guide にいろいろ面白そうな機能が書かれているので、試してみます。

履歴

2017/05/10
初版発行。