はじめに
springBoot3勉強中に知った「groovy templates」というテンプレートエンジン。ほかのテンプレートエンジン(Thymeleaf等)と違ってHTMLタグではなくGroovyのコードで画面表示をつくるのが面白そう。ということで試してみました。
まず参考文献
「Spring Boot 3 プログラミング入門」(https://www.shuwasystem.co.jp/book/9784798069166.html)⇒Chapter3, Chapter4
環境
- 開発環境:Eclipse 2022-12 (4.26.0)
- Java 17.0.5
- フレームワーク:SpringBoot 3.1.0
- ビルドツール:gradle
準備
プロジェクト新規作成
ファイル > 新規 > Spring スターター・プロジェクトgradle
dependenciesに追加した- 「spring-boot-starter-groovy-templates」・・・Groovy templatesテンプレートエンジン
- 「spring-boot-starter-web」・・・Webパッケージ
- 「spring-boot-starter-data-jpa」・・・DBアクセスするために必要
- 「spring-boot-starter-test」・・・コードテストするために必要
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.2'
id 'io.spring.dependency-management' version '1.1.2'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-groovy-templates'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
設定ファイル(groovyの設定)
- 「cache=false」・・・キャッシュOFF
- 「suffix=.tpl」・・・ビュー名に追加される拡張子はtpl
application.properties
spring.groovy.template.cache=false
spring.groovy.template.suffix=.tpl
アプリケーションクラス(自動生成されたまま)
GroovyStudyApplication.java
package com.example.groovy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GroovyStudyApplication {
public static void main(String[] args) {
SpringApplication.run(GroovyStudyApplication.class, args);
}
}
テーブル
繰り返し表示させてみるAccountテーブルの設定Account.java
package com.example.groovy;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name="account")
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private long id;
@Column(length = 50, nullable = false)
private String name;
@Column(length = 200, nullable = true)
private String mail;
public Account() {
}
public Account(String name, String mail) {
this.name = name;
this.mail = mail;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getMail() {
return mail;
}
}
AccountRepository.java
package com.example.groovy.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.groovy.Account;
@Repository
public interface AccountRepository extends JpaRepository<Account, Long> {
}
コントローラークラス
initメソッド | インスタンス生成後に呼び出される(PostConstructアノテーションによって) Accountテーブルにデータ投入している |
getDataメソッド | GET /getData アクセス時に呼び出される mav.setViewName("getData");で画面表示に使うテンプレートを指定(getData.tpl) |
IndexController.java
package com.example.groovy.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.servlet.ModelAndView;
import com.example.groovy.Account;
import com.example.groovy.repositories.AccountRepository;
import jakarta.annotation.PostConstruct;
@Controller
public class IndexController {
@Autowired
AccountRepository repository;
@PostConstruct
public void init() {
List<Account> accountList = new ArrayList<>();
accountList.add(new Account("ichiro", "example1@example.com"));
accountList.add(new Account("jiro", "example2@example.com"));
accountList.add(new Account("saburo", "example3@example.com"));
repository.saveAllAndFlush(accountList);
}
@GetMapping("/getData")
public ModelAndView getData(@ModelAttribute("formModel") Account account, ModelAndView mav) {
mav.setViewName("getData");
mav.addObject("title", "タイトル表示");
mav.addObject("message", "メッセージ表示");
mav.addObject("flag1", true);
mav.addObject("flag2", false);
Iterable<Account> list = repository.findAll();
mav.addObject("data", list);
return mav;
}
}
テンプレート
getData.tpl
yieldUnescaped '<!DOCTYPE html>'
html(lang:'ja') {
head {
meta(charset:"UTF-8")
title("繰り返し")
link(rel:"stylesheet", type:"text/css",
href:"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css")
}
body(class:"container"){
h1(class:"display-4 mb-4", title)
p(message)
div (class:"alert alert-primary") {
if (flag1) {
p("flag1がtrueの時に出力されるよ")
} else {
p("flag1がfalseだったら出力")
}
if (flag2) {
p("flag2がtrueの時に出力されるよ")
} else {
p("flag2がfalseだったら出力")
}
}
div (class:"card") {
div (class:"card-body") {
h3(class:"card-title", "アカウント一覧")
data.each {
p(class:"card-text", it.id + "/" + it.name + "/" + it.mail)
}
}
}
}
}
⇒実行してみる!(プロジェクトを右クリック > 実行 > Spring Boot アプリケーション)