JTE:Spring Boot新Java模板引擎

JTE是一个模板引擎,用于在 Spring Boot 应用程序中开发使用 Java 语法的用户界面应用程序,与 Freemarker、Thymeleaf、Mustache 和 Velocity 等其他引擎并驾齐驱。

许多开发人员广泛使用 Spring Boot(一个简化 Java 应用程序开发的框架),而像我这样的模板引擎则简化了创建动态和响应式用户界面的过程。

JTE 文档强调,Java Template Engine(jte) 是为 Java 和 Kotlin 量身定制的安全高效的解决方案。 JTE 旨在尽量减少新关键字的引入,并使用现有的语言特性,从而简化对模板功能的理解。

特点:

  • 提供简化且用户友好的语法。
  • 你可以用纯 Java 或 Kotlin 编写表达式。
  • 系统在编译时执行上下文感知的 HTML 转义。
  • IntelliJ 插件 提供了 Intellisense 和重构功能。
  • 自动重新加载功能在开发过程中出现。
  • 保证提高执行速度。有关更多详细信息,请参阅此链接

Java 模板引擎(JTE)能够与各种框架集成。

  1. Spring MVC
  2. Spring Boot
  3. Ktor
  4. Micronaut
  5. Quarkus
  6. Javalin
  7. Eclipse Vert.x
  8. Severell
  9. http4k

Mave:

<dependency>
 <groupId>gg.jte</groupId>
 <artifactId>jte</artifactId>
 <version>3.1.13</version>
</dependency>

Gradle:

implementation("gg.jte:jte:3.1.13")

要呈现任何模板,您必须为整个应用程序使用一个 gg.jte.TemplateEngine 实例。

import gg.jte.ContentType;
import gg.jte.TemplateEngine;
import gg.jte.CodeResolver;
import gg.jte.resolve.DirectoryCodeResolver;

// ...

CodeResolver codeResolver = new DirectoryCodeResolver(Path.of("jte")); // 这是存放 .jte 文件的目录。
TemplateEngine templateEngine = TemplateEngine.create(codeResolver, ContentType.Html);

完全初始化模板引擎实例后,我们就可以开始渲染模板了。

import gg.jte.TemplateOutput;
import gg.jte.output.StringOutput;

// ...

TemplateOutput templateOutput = new StringOutput();
templateEngine.render("home.jte", model, templateOutput);

在这里,templateOutput(模板输出)一词表示模板渲染的位置。

  • gg.jte.output.StringOutput--以字符串形式生成输出。
  • gg.jte.output.FileOutput--将内容写入指定的 java.io.File。
  • gg.jte.output.PrintWriterOutput--输出到 PrintWriter,例如从 HttpServletRequest 获取的 writer。
  • gg.jte.output.WriterOutput - 将数据传输到 java.io.Writer 中。

SpringBoot实例 模型指的是提供给该模板的数据,可以是任何类的实例。 现在,我们就来参与一个实际的 Spring Boot 示例。 第一步:访问 start.spring.io 第二步:选择项目、语言、Spring Boot 版本(最好是已发布的版本)、项目元数据以及 Java 版本 第三步:在依赖选择下,请添加 Web 和 JTE(模板引擎)依赖 第四步:然后生成并下载项目

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bsmlabs</groupId>
    <artifactId>spring-boot-jte</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-jte</name>
    <description>Spring Boot Project with Java Template Engine</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>23</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>gg.jte</groupId>
            <artifactId>jte</artifactId>
            <version>3.1.13</version>
        </dependency>
        <dependency>
            <groupId>gg.jte</groupId>
            <artifactId>jte-spring-boot-starter-3</artifactId>
            <version>3.1.13</version>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>gg.jte</groupId>
                <artifactId>jte-maven-plugin</artifactId>
                <version>3.1.13</version>
                <executions>
                    <execution>
                        <id>jte-generate</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <sourceDirectory>${project.basedir}/src/main/jte</sourceDirectory>
                            <contentType>Html</contentType>
                            <binaryStaticContent>true</binaryStaticContent>
                            <targetResourceDirectory>${project.build.outputDirectory}</targetResourceDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
解压缩项目并导入 IntelliJ /Eclipse IDE 让我们创建一个名为 IndexController 的简单控制器,并创建带有实例字段的页面布局

package com.bsmlabs.jte;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class IndexController {

    @GetMapping("/")
    public String getIndex(Model model) {
       model.addAttribute("name", "Welcome To Java Template Engine");
       model.addAttribute("page", new Page("Hello JTE", "JTE Application"));

       return "index";
    }
}
package com.bsmlabs.jte;

public record Page(String title, String description) {
}

下一步是在 /src/main/jte 文件夹中创建一个 index.jte 模板,该目录是在 start.spring.io 生成过程中建立的。

@import com.bsmlabs.jte.Page

@param String name
@param Page page

<!DOCTYPE html>
<html lang="en">
<head>
    <title>${page.title()}</title>
    @if(page.description() != null)
       <meta name="description" content="${page.description()}">
    @endif
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<nav class="bg-gray-800">
    <div class="hidden sm:ml-6 sm:block">
        <div class="flex space-x-4">
            <a href="#" class="rounded-md bg-gray-900 px-3 py-2 text-sm font-medium text-white" aria-current="page">Dashboard</a>
            <a href="#" class="rounded-md px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Blog</a>
            <a href="#" class="rounded-md px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Projects</a>
        </div>
    </div>
</nav>
<p class="text-slate-700 dark:text-slate-500 font-medium">${name}!</p>
</body>
</html>
在此上下文中,
  • 指令 @import 与 Java 导入直接对应,从而确保 com.bsmlabs.jte.Page 被模板识别。
  • 该模板所需的参数是 Page 对象,即 @param Page page
  • @if/@endif 结构表示 if 块。括号内的内容(page.getDescription() != null)由标准 Java 代码组成。
  • ${} 用于在表达式中写入模板输出。

我们将在 application.properties 中添加以下属性

# 当 developmentMode 设置为 true 时,jte 文件监视器将监控模板更改并相应地重新编译。
gg.jte.development-mode=true

spring.application.name=spring-boot-jte

# 默认情况下,模板文件位于 /src/main/jte
gg.jte.templateLocation=src/main/jte

# 用 templateSuffix 表示 .jte
gg.jte.templateSuffix=.jte

由于我们使用 Spring Boot 进行开发,并结合了 spring-boot-starter-web 起动器,因此 org.springframework.web.servlet.ViewResolver 和 templateEngine 都将自动配置。

结论 通过将 Java 模板引擎 (JTE) 集成到各种框架中,人们可以体验到一种新颖的方法,这种方法具有显著的优势,包括卓越的性能、更高的并发性和更快的模板渲染。

代码: Github.