Spring Boot Thymeleaf——使用 Thymeleaf 引擎创建视图

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(350)   2023-06-26 07:54:18

Spring Boot Thymeleaf 教程展示了如何使用 Thymeleaf 模板引擎和 H2 数据库创建一个简单的 Spring Boot Web 应用程序。

春天 是一个流行的 Java 应用程序框架。 弹弓贴 致力于以最小的努力创建独立的、生产级的基于 Spring 的应用程序。

氢气 是一个完全用 Java 创建的开源关系数据库管理系统。它可以嵌入到 Java 应用程序中,也可以运行在客户端-服务器模式下。它易于部署和安装,占用空间小。

百里香叶

百里香叶 是一个现代服务器端 Java 模板引擎,适用于 Web 和独立环境。它建立在自然模板的概念之上:可以在浏览器中直接打开并且仍然正确显示为网页的模板文件。当 Spring Boot 在 Maven POM 文件中找到依赖项时,它会自动配置 Thymeleaf。

Spring Boot Thymeleaf 示例

下一个示例创建一个使用 Thymeleaf 引擎的 Spring Boot Web 应用程序。数据存储在H2数据库中。

build.gradle
...
src
├── main
│   ├── java
│   │   └── com
│   │       └── zetcode
│   │           ├── Application.java
│   │           ├── controller
│   │           │   └── MyController.java
│   │           ├── model
│   │           │   └── City.java
│   │           └── service
│   │               ├── CityService.java
│   │               └── ICityService.java
│   └── resources
│       ├── application.properties
│       ├── application.yml
│       ├── data-h2.sql
│       ├── schema-h2.sql
│       ├── static
│       │   └── css
│       │       └── style.css
│       └── templates
│           ├── cities.html
│           └── index.html
└── test
    ├── java
    └── resources

这是项目结构。默认情况下,Thymeleaf 模板文件位于 src/main/resources/templates 目录中。

build.gradle
plugins {
    id 'org.springframework.boot' version '2.6.7'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

    runtimeOnly 'com.h2database:h2'
}

这是 Maven 构建文件。 spring-boot-starter-thymeleaf 是使用 Thymeleaf 构建 Spring MVC 应用程序的入门工具。 spring-boot-starter-jdbc 是在 Spring Boot 中使用 JDBC 的启动器。 h2 包含 H2 数据库引擎。

com/zetcode/model/City.java
package com.zetcode.model;

import java.util.Objects;
import java.util.StringJoiner;

public class City {

    private Long id;
    private String name;
    private int population;

    public City() {
    }

    public City(Long id, String name, int population) {
        this.id = id;
        this.name = name;
        this.population = population;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        City city = (City) o;
        return population == city.population &&
                Objects.equals(id, city.id) &&
                Objects.equals(name, city.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, population);
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", City.class.getSimpleName() + "[", "]")
                .add("id=" + id)
                .add("name='" + name + "'")
                .add("population=" + population)
                .toString();
    }
}

这是 City 模型类。它包含项目 ID、名称和人口属性。

resources/application.yml
spring:
  main:
    banner-mode: off
    log-startup-info: false
  sql:
    init:
      platform: h2

application.yml 是主要的 Spring Boot 配置文件。通过 banner-mode 属性,我们关闭了 Spring 横幅。通过 log-startup-info 属性,我们关闭了 Spring Boot 启动日志消息。平台值用于 SQL 初始化脚本:schema-${platform}.sqldata-${platform}.sql

请注意,我们没有配置数据源;如果没有配置数据,Spring会自动将H2配置为in-memory模式。我们想要一个内存数据库,所以我们让 Spring 来做自动配置。

resources/schema-h2.sql
CREATE TABLE cities(id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255), population INT);

此 SQL 脚本创建 cities 表。

resources/data-h2.sql
INSERT INTO cities(name, population) VALUES('Bratislava', 432000);
INSERT INTO cities(name, population) VALUES('Budapest', 1759000);
INSERT INTO cities(name, population) VALUES('Prague', 1280000);
INSERT INTO cities(name, population) VALUES('Warsaw', 1748000);
INSERT INTO cities(name, population) VALUES('Los Angeles', 3971000);
INSERT INTO cities(name, population) VALUES('New York', 8550000);
INSERT INTO cities(name, population) VALUES('Edinburgh', 464000);
INSERT INTO cities(name, population) VALUES('Berlin', 3671000);

此脚本用数据填充表。这两个脚本都位于类路径的根目录中。

com/zetcode/service/ICityService.java
package com.zetcode.service;

import com.zetcode.model.City;
import java.util.List;

public interface ICityService {

    List<City> findAll();
}

ICityService 提供了一个从数据源中获取所有城市的契约方法。

com/zetcode/service/CityService.java
package com.zetcode.service;

import com.zetcode.model.City;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CityService implements ICityService {

    private final JdbcTemplate jtm;

    public CityService(JdbcTemplate jtm) {
        this.jtm = jtm;
    }

    @Override
    public List<City> findAll() {

        String sql = "SELECT * FROM cities";

        return jtm.query(sql, new BeanPropertyRowMapper<>(City.class));
    }
}

CityService 包含 findAll() 方法的实现。我们在 JdbcTemplate 的帮助下从 cities 表中检索所有城市。

private final JdbcTemplate jtm;

public CityService(JdbcTemplate jtm) {
    this.jtm = jtm;
}

JdbcTemplate 被注入。

String sql = "SELECT * FROM cities";

这是要执行的SQL。我们从 cities 表中选择所有城市。

return jtm.query(sql, new BeanPropertyRowMapper<>(City.class));

BeanPropertyRowMapper 将行转换为指定映射目标类的新实例。

com/zetcode/controller/MyController.java
package com.zetcode.controller;

import com.zetcode.model.City;
import com.zetcode.service.ICityService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class MyController {

    private final ICityService cityService;

    public MyController(ICityService cityService) {
        this.cityService = cityService;
    }

    @GetMapping("/")
    public String index(Model model) {

        return "index";
    }

    @GetMapping("/cities")
    public ModelAndView showCities() {

        List<City> cities = cityService.findAll();

        Map<String, Object> params = new HashMap<>();
        params.put("cities", cities);

        return new ModelAndView("cities", params);
    }
}

这是 Spring Boot Web 应用程序的控制器类。控制器用 @Controller 注释装饰。控制器有两个映射:一个用于主页的映射,一个用于列出所有引用。当 Spring Boot 在 Maven POM 文件中检测到 Thymeleaf 启动器时,它会自动配置 Thymeleaf 视图。

private final ICityService cityService;

public MyController(ICityService cityService) {
    this.cityService = cityService;
}

我们将 CityService 注入该字段。

@GetMapping("/")
public String index(Model model) {

    return "index";
}

"index" 是位于预定义 template 目录中的视图的名称。这是一个简单的静态主页。

@GetMapping("/cities")
public ModelAndView showCities() {

    List<City> cities = cityService.findAll();

    Map<String, Object> params = new HashMap<>();
    params.put("cities", cities);

    return new ModelAndView("cities", params);
}

此控制器方法提供城市列表。我们从城市服务中找到所有城市对象,并将结果列表放入参数中。 Spring 将定位名为 cities 的 Thymeleaf 视图,并让引擎将模板与模型数据连接起来。

resources/static/css/style.css
h2 {color: blue}

style.css 是位于 src/main/resources/static/css 目录中的静态文件。它将 h2 标签设置为蓝色。

resources/templates/index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Home page</title>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </head>
    <body>
        <a href="cities">Show cities</a>
    </body>
</html>

index.html 是应用程序的主页。它包含一个链接来检索所有城市。

resources/templates/cities.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Cities</title>
    <link rel="stylesheet" th:href="@{/css/style.css}" />
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>

<h2>List of cities</h2>

<table>

    <tr>
        <th>Id</th>
        <th>Name</th>
        <th>Population</th>
    </tr>

    <tr th:each="city : ${cities}">
        <td th:text="${city.id}">id</td>
        <td th:text="${city.name}">name</td>
        <td th:text="${city.population}">price</td>
    </tr>

</table>

</body>
</html>

cities.html 是一个 Thymeleaf 模板文件,其中包含要用模型中的数据填充的占位符。要访问数据,我们使用 ${} 变量表达式。

<link rel="stylesheet" th:href="@{/css/style.css}" />

我们包含带有 Thymeleaf 链接表达式的静态 CSS 文件@{}。链接表达式自动添加服务器上下文路径 (myapp)。

<tr th:each="city : ${cities}">
    <td th:text="${city.id}">id</td>
    <td th:text="${city.name}">name</td>
    <td th:text="${city.population}">price</td>
</tr>

我们遍历城市列表并将每个城市的详细信息放入一个表行中。

com/zetcode/Application.java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

我们设置了 Spring Boot 应用程序。 @SpringBootApplication 注释启用自动配置和组件扫描。

$ ./gradlew bootRun

我们运行应用程序并定位到 localhost:8080

在本教程中,我们使用 Thymeleaf 和 H2 创建了一个 Spring Boot Web 应用程序。

地址:https://www.cundage.com/article/springboot-thymeleaf.html

相关阅读

Spring Boot Vue.js 教程展示了如何使用 Vue.js 框架创建一个简单的 Spring Boot。 Vue.js Vue.js 是一个用于构建用户界面的 JavaScript ...
JavaScript 是否已经取代 Java 成为新的“一次编写,随处运行”的编程语言?这完全取决于您的观点。随着 WebAssembly 等技术的出现,Java 可以在新奇的“一次编写,随处编...
Usage of TypeScript,微软基于 JavaScript 的强类型语言, has soared compared to six years ago, according to th...
云莓将基于 Spring 构建的 Java 后端与使用 Lit 构建的 TypeScript 前端相结合,一个快速、响应式的 JavaScript 框架。基于 Vaadin Fusion 的 H...
本博客严重偏向于 GWT(和基于 GWT 的框架),但我们牢记 GWT 将来可能会被其他技术接管,因此我们始终对探索其他平台/框架持开放态度。正如他们所说,多元化可以降低风险。每种编程语言,即使...
Java JSON 教程展示了如何使用 JSON-Java 在 Java 中进行 JSON 序列化和反序列化。 JSON(JavaScript 对象显示法) 是一种轻量级数据交换格式。人类易于读...
JHipster 是一个长期存在且雄心勃勃的混合 Java 和 JavaScript 项目,致力于使用现代反应式前端简化全栈 Java 应用程序的开发。 JHipster 开发团队不断发布新版本...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Spring Boot JSON 教程展示了如何在 Spring Boot 注释中提供 JSON 数据。 春天 是一个流行的 Java 应用程序框架,弹簧贴 是 Spring 的演变,有助于创建...
根据最近一项全球开发人员调查,在开发人员偏好方面,JavaScript 和 Python 保持了持久力,而 锈 的使用率正在上升. 5 月 4 日的一份题为“开发者国家情况,第 22nd 版”的...