欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Thymeleaf模板引擎——JSP替代方案

程序员文章站 2022-05-01 23:17:56
...

介绍Thymeleaf模板引擎

 

翻译自 阿尔诺COGOLUÈGNES 的文章

有一堆Java模板引擎,但其中一个现在已经获得了一些动力:Thymeleaf。良好而强大的语法,灵活性,充满活力的社区以及与流行Web技术的良好集成,这些都是发现JSP替代方案的充分理由。本文列出了Thymeleaf的核心功能,并展示了如何编写和处理HTML模板。

 

Thymeleaf简而言之

Thymeleaf是一个Java模板引擎。它是一个开源项目,并根据Apache License 2.0获得许可。以下是Thymeleaf的核心功能:

  • 简单而自然的模板
  • 针对Web环境进行了优化,但可以独立运行
  • 高级评估语言(OGNLSpring Expression Language
  • 支持模板逻辑(条件,迭代)
  • 全力支持国际化
  • Spring MVC和Spring Web Flow集成
  • 支持复合视图模式(带有片段的本机,Tiles集成,可与Sitemesh一起使用)
  • 先进的模板缓存支持
  • 适用于蒲公英数据表

是的,这是很多功能!继续阅读以了解如何使用数据编写和提供Thymeleaf模板...

Maven 最新模板依赖

<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf -->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.10.RELEASE</version>
</dependency>

 

设置模板引擎

Thymeleaf基础设施非常简单:a TemplateResolver加载模板和a TemplateEngine进行实际处理(使用给定的上下文合并模板)。以下是独立设置的代码:

 

1

2

3

4

5

ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();

resolver.setTemplateMode("XHTML");

resolver.setSuffix(".html");

TemplateEngine engine = new TemplateEngine();

engine.setTemplateResolver(resolver);

我们将从类路径的根目录加载模板。当我们要求Thymeleaf呈现一个名为的模板时home,解析器将添加html扩展名,因为我们设置了该suffix属性。然后,我们将能够根据逻辑名称进行思考,并且不会担心文件的物理名称。

模板

我们的模板是home.html位于类路径根目录的文件(例如,src/main/resources如果我们遵循Maven约定,则在项目目录中)。模板的第一个版本仅包含HTML页面的骨架:

 

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-3.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"

      xmlns:th="http://www.thymeleaf.org">

<head>

    <title>My first template with Thymeleaf</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>

<body>

</body>

</html>

请注意使用特定于Thymeleaf的doctype。

处理模板

我们的模板中没有任何动态,但我们可以通过在引擎配置后添加以下代码来测试我们的设置:

 

1

2

3

StringWriter writer = new StringWriter();

Context context = new Context();

engine.process("home", context, writer);

然后,writer变量应包含已处理模板的输出,该输出基本上是文件的静态内容。重要的事情:

处理需要上下文。该对象通常包含我们想要在视图中显示的变量。

要调用要渲染的模板home。解析器将负责将此逻辑名称映射到文件的物理位置。请记住,我们使用的是基于类路径的解析器,它为模板名称添加了HTML扩展。

好的,一切似乎都有效!了解Thymeleaf是如何轻量级的。模板引擎大部分时间都在Web环境中使用,但我们也可以在独立环境中轻松使用它,比如JUnit测试。

标签和国际化(i18n)

Thymeleaf的默认国际化支持非常简单:删除模板旁边的属性文件,您就完成了。让我们home.properties在与模板相同的目录中创建一个:

 

1

hello.world=Hello World!

还有一个home_fr.properties法文版的文件:

 

1

hello.world=Bonjour le monde !

我们修改模板以引用此标签:

 

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-3.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"

      xmlns:th="http://www.thymeleaf.org">

<head>

    <title>My first template with Thymeleaf</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>

<body>

    <p th:text="#{hello.world}">Hello</p>

</body>

</html>

就是这样,我们公开了如何在Thymeleaf的模板中插入动态内容:在HTML元素中添加额外的属性:

 

1

<p th:text="#{hello.world}">Hello</p>

嵌套Hello只是为了预览,Thymeleaf将在处理过程中用动态值替换它。请注意使用Thymeleaf的特定th:text属性以及使用#{key}语法来引用属性文件的条目。

如果我们执行渲染程序,我们最终得到以下输出(如果你的语言环境不是法语!):

 

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>My first template with Thymeleaf</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>

<body>

    <p>Hello World!</p>

</body>

</html>

法语版怎么样?我们可以在上下文中指定语言环境:

 

1

2

3

StringWriter writer = new StringWriter();

Context context = new Context(Locale.FRANCE);

engine.process("home", context, writer);

Thymeleaf使用适当的属性文件:

 

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>My first template with Thymeleaf</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>

<body>

    <p>Bonjour le monde !</p>

</body>

</html>

到目前为止,非常好,让我们继续讨论核心主题:在上下文中推送对象以在视图中呈现它们。

变量替换

我们假设我们想在视图中显示当前日期。我们可以使用已经格式化的字符串提供上下文:

 

1

2

String now = new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime());

context.setVariable("date", now);

然后在模板中引用此变量,如下所示:

 

1

<p th:text="${date}">The date</p>

注意这次使用${variable}语法(我们用于#{...}i18n)。我们再次依靠该th:text属性来注入动态内容。如果我们再次处理模板,则输出包含预期的内容:

 

1

<p>2013-01-18</p>

让我们看看如何显示典型的域对象。

使用Java bean进行变量替换

显示域对象是Web应用程序的常见用例。我们可以添加一个Contact对象来显示Thymeleaf上下文:

 

1

context.setVariable("contact",new Contact("John","Doe"));

我们对域对象状态进行了硬编码,但它也可以从数据库中加载。以下是如何显示firstnamelastname域对象的属性:

 

1

2

3

4

<div>

     <p>First name: <span th:text="${contact.firstname}">First name</span></p>

     <p>Last name: <span th:text="${contact.lastname}">Last name</span></p>

</div>

正如您所看到的,${...}Thymeleaf中的内容可能是一个复杂的表达式,而不仅仅是对变量的引用。Thymeleaf使用OGNL作为其默认处理引擎,开启了广泛的可能性:运营商,连接等。

现在让我们看一个额外的功能,它可以缩短Java对象的显示。

选择语法的详细程度较低

Thymeleaf允许对对象执行选择。一旦选择了一个对象,它就可以作为评估上下文中的某种第一级变量。然后我们可以使用*{...}语法而不是语法来引用它${...}

在我们的模板中,我们可以contact使用通常的${...}语法选择对象,然后使用以下*{...}语法引用其属性:

 

1

2

3

4

<div th:object="${contact}">

    <p>First name: <span th:text="*{firstname}">First name</span></p>

    <p>Last name: <span th:text="*{lastname}">Last name</span></p>

</div>

我们最终得到完全相同的渲染,但模板代码更简单。不错,不是吗?

迭代

Web应用程序的另一个常见用例是在表中显示数据:我们从数据库中加载Java对象列表并将它们显示在HTML表中。想象一下,我们用以下方式提供上下文List<Contact>

 

1

2

3

4

5

6

Context context = new Context();

List<Contact> contacts = new ArrayList<Contact>();

contacts.add(new Contact("John","Doe"));

contacts.add(new Contact("Jane","Doe"));

context.setVariable("contacts",contacts);

engine.process("home", context, writer);

迭代列表,我们使用th:each属性:

 

1

2

3

4

5

6

7

8

9

10

<table>

    <tr>

        <th>Firstname</th>

        <th>Lastname</th>

    </tr>

    <tr th:each="contact : ${contacts}">

         <td th:text="${contact.lastname}">The first name</td>

         <td th:text="${contact.firstname}">The last name</td>

     </tr>

</table>

我们最终得到了这个输出:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

<table>

    <tr>

        <th rowspan="1" colspan="1">Firstname</th>

        <th rowspan="1" colspan="1">Lastname</th>

    </tr>

    <tr>

         <td rowspan="1" colspan="1">Doe</td>

         <td rowspan="1" colspan="1">John</td>

    </tr><tr>

         <td rowspan="1" colspan="1">Doe</td>

         <td rowspan="1" colspan="1">Jane</td>

    </tr>

</table>

 

注意Thymeleaf 根据所选XHTML 1.0 Strict标准的DTD 添加了一些rowspancolspan属性。如果我们告诉它符合HTML 5,Thymeleaf就不会生成它们。

在完成我们对Thymeleaf的发现之前,让我们玩条件语句。

条件,«if»语法

想象一下,如果联系人列表为空,我们不想显示空表,我们可以轻松检查列表的大小,如果列表不为空,则选择显示整个表

 

1

2

3

4

5

6

7

8

9

10

<table th:if="${not #lists.isEmpty(contacts)}">

    <tr>

        <th>Firstname</th>

        <th>Lastname</th>

    </tr>

    <tr th:each="contact : ${contacts}">

         <td th:text="${contact.lastname}">The first name</td>

         <td th:text="${contact.firstname}">The last name</td>

     </tr>

</table>

 

请注意使用#lists实用程序对象来检查列表是否为空。

结论

本文介绍了Thymeleaf的基本模板特征。Thymeleaf旨在用于Web应用程序,但它的灵活性使我们可以在独立环境中使用它。Thymeleaf不需要JSP编译器,可以从任何地方获取模板(文件系统,Web上下文,类路径)。您甚至可以将整个Web应用程序打包到一个简单的JAR中,这是迈向模块化的重要一步!Thymeleaf有很多功能,我们将在后续文章中看到如何将它与Spring MVC集成。

英文原文链接:https://blog.zenika.com/2013/01/18/introducing-the-thymeleaf-template-engine/

 

相关标签: Thymeleaf