JavaWeb进阶指南:Servlet与Thymeleaf整合全流程详解

大家好,我是袁庭新。今天介绍Servlet和Thymeleaf的整合过程。接下来,让我们一同深入探究其详细步骤与操作要点。

1.下载Thymeleaf依赖

想要使用Thymeleaf进行JavaWeb应用的开发,第一步就是要下载Thymeleaf的依赖包,具体步骤如下。

1.1 手动下载Thymeleaf依赖

1.使用浏览器访问Thymeleaf官网(www.thymeleaf.org),选择上方的【Download】按钮,如下图。

从上图可知,Thymeleaf当前最新版本为Thymeleaf 3.1.2.RELEASE,该版本要求Java SE的版本为8或更新的版本,这里我们使用的Java SE版本为11。

2.Thymeleaf官网为我们提供了多种引入Thymeleaf依赖的方式,例如Maven、Gradle以及直接下载Thymeleaf分发包和源码等。我们可以根据需要选择合适自己的方式来下载Thymleaf的依赖,如下图。

3.点击【Distribution packages】下方的【GitHub's releases distribution】链接,如下图所示。

4.跳转到GitHub页面,在Thymeleaf 3.1.2.RELEASE下的【Assets】中,点击"thymeleaf-3.1.1.RELEASE-dist.zip"下载发行包,如下图。

5.下载完成后,解压thymeleaf-3.1.2.RELEASE-dist.zip压缩包,可得到以下目录结构。

1.2 坐标下载Thymeleaf依赖

采用上述手动方式下载Thymeleaf依赖过于麻烦,如果我们的项目是Maven类型,将Thymeleaf添加到项目中最简单的方式是,并利用中央存储库中的Thymeleaf,你只需将所需的Thymeleaf依赖项添加到你的项目的pom.xml中即可。例如:

xml 复制代码
<dependency>
  <groupId>org.thymeleaf</groupId>
  <artifactId>thymeleaf</artifactId>
  <version>3.1.2.RELEASE</version>
</dependency>

2.配置模板引擎

2.1 模板引擎介绍

Thymeleaf的核心依赖包(thymeleaf-3.1.2.RELEASE.jar)中提供了一个名为TemplateEngine(模板引擎)的类。TemplateEngine类是Thymeleaf中最核心、最重要的类之一,Thymeleaf就是通过它来解析模板文件(例如HTML文件、XML文件、CSS文件等),最终渲染成动态网页进行展示的。

TemplateEngine类中包含了许多实用方法,其中最常用的就是下表中列出的这两个方法。

java 复制代码
public void setTemplateResolver(final ITemplateResolver templateResolver)

在使用TemplateEngine对模板文件进行处理之前,通常都需要为它设置一个ITemplateResolver类型的对象作为其模板解析器。通过这个ITemplateResolver(模板解析器)对象,我们可以对以下内容进行设置:

  • 模板文件的路径,包括前缀(prefix)和后缀(suffix);
  • 模板模式(TemplateMode):包括HTML、XML、TEXT、JAVASCRIPT、CSS、RAM等6种模式;
  • 缓存是否可用;
  • 缓存时间等。
java 复制代码
public final void process(final String template, final IContext context, final Writer writer)

模板引擎通过该方法实现对模板文件的解析,并最终渲染成一个动态网页。

对于一个JavaWeb应用而言,它只需要配置一个Thymeleaf模板引擎即可,因此这里我们需要使用单例模式对TemplateEngine进行配置,具体实现方式如下。

2.2 模板引擎实现

1.创建一个类型为Java Enterprise名为servlet-thymeleaf-project的JavaWeb项目。项目的GAV坐标中GroupId的值设置为com.ytx,其他保持默认。

2.在servlet-thymeleaf-project项目的pom.xml文件中添加如下的依赖。

xml 复制代码
<?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>

  <groupId>com.ytx</groupId>
  <artifactId>servlet-thymeleaf-project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>servlet-thymeleaf-project</name>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
    <junit.version>5.8.1</junit.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <!-- Servlet依赖 -->
    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>6.0.0</version>
    </dependency>
    <!-- Thymeleaf依赖 -->
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf</artifactId>
      <version>3.1.2.RELEASE</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
      </plugin>
    </plugins>
  </build>
</project>

3.这里我们引入的Servlet依赖版本是6.0.0,此版本的Servlet需要运行在Apache Tomcat 10.1.x版本上。因此,需要确保你电脑上安装的Tomcat版本正确。Apache官方对各版本的解释:tomcat.apache.org/whichversio...。这里我们对Tomcat的安装不展开介绍。

4.在servlet-thymeleaf-project项目的src目录下,创建一个com.ytx.thymeleaf包,并在该包下创建一个名为CustomTemplateEngine的Java类,通过该类对Thymeleaf的模板引擎进行配置,代码如下。

java 复制代码
package com.ytx.thymeleaf;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.WebApplicationTemplateResolver;
import org.thymeleaf.web.servlet.IServletWebExchange;
import org.thymeleaf.web.servlet.JakartaServletWebApplication;
import java.io.IOException;

/**
 * 对于一个JavaWeb应用而言,我们只需要配置一套模板引擎即可,所有的请求都通过该模板引擎来解析网页。
 * 单例模式。本类中还提供了一个对请求进行解析的方法,方便我们使用。
 */
public class CustomTemplateEngine {
    private static CustomTemplateEngine webApplication;
    private TemplateEngine templateEngine;
    private JakartaServletWebApplication application;

    /** 单例模式:构造方法私有化处理 */
    private CustomTemplateEngine(HttpServletRequest request) {
        System.out.println("设置Thymeleaf模板引擎");
        // 创建Thymeleaf的JakartaServletWebApplication对象
        application = JakartaServletWebApplication.buildApplication(request.getServletContext());
        // 创建模板解析器对象
        final WebApplicationTemplateResolver templateResolver = new WebApplicationTemplateResolver(application);
        // 设置Thymeleaf的模板模式为HTML,除此之外Thymeleaf还支持处理其他5种模板,它们分别是XML、TEXT、JAVASCRIPT、CSS、RAW
        templateResolver.setTemplateMode(TemplateMode.HTML);
        // 设置模板文件的前缀(即路径)
        templateResolver.setPrefix("/WEB-INF/templates/");
        // 设置模板文件的文件后缀
        templateResolver.setSuffix(".html");
        // 设置缓存时间
        templateResolver.setCacheTTLMs(Long.valueOf(3600000L));
        // 设置缓存是否可用,开发阶段我们需要将缓存关闭,即设置为false
        templateResolver.setCacheable(false);
        // 创建模板引擎对象
        templateEngine = new TemplateEngine();
        // 为模板引擎设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);
    }

    /**
     * 获取WebApplication对象
     * @param request 请求对象
     * @return 返回CustomTemplateEngine对象
     */
    public static CustomTemplateEngine getInstance(HttpServletRequest request) {
        if (webApplication == null) {
            webApplication = new CustomTemplateEngine(request);
        }
        return webApplication;
    }

    /**
     * 处理模板文件
     * @param templateName 模板文件的名称
     * @param request 请求对象
     * @param response 响应对象
     * @throws IOException IO异常
     */
    public void processTemplate(String templateName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 创建IServletWebExchange对象
        IServletWebExchange webExchange = application.buildExchange(request, response);
        // 创建WebContext对象
        WebContext context = new WebContext(webExchange, webExchange.getLocale());
        // 设置响应体内容类型和字符集
        response.setContentType("text/html;charset=UTF-8");
        // 处理模板数据
        templateEngine.process(templateName, context, response.getWriter());
    }
}

这里我们采用了单例模式,CustomTemplateEngine中包含了一个私有(private)的构造方法以及一个返回其自身实例的getInstance()方法。在这个私有的构造方法中,我们对模板引擎TemplateEngine对象进行了配置,并使用WebApplicationTemplateResolver对象作为其模板解析器,分别配置了模板模式、模板文件的前缀和后缀、缓存等内容。

此外,CustomTemplateEngine类中还包含了一个processTemplate()方法,该方法内部对TemplateEngine实例的process()方法进行了调用。Servlet在处理完请求后,直接调用这个方法便可以对指定的模板文件进行访问。

温馨提示:对CustomTemplateEngine这个类,我们只需要理解其基本思想和原理即可,不用刻意的去记住代码。后面我们使用SpringMVC、Spring Boot等JavaWeb框架对Thymeleaf进行整合时仍然会涉及到这些配置,那时我们都是通过配置文件实现的,使用起来也更加方便。

3.在Servlet中使用Thymeleaf

在项目的src/main/java目录下新建一个com.ytx.servlet包,并在该包下创建一个名为IndexServlet的Servlet类,代码如下。

java 复制代码
package com.ytx.servlet;
import com.ytx.thymeleaf.CustomTemplateEngine;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doGet()方法执行...");
        // 获取CustomTemplateEngine实例,对TemplateEngine对象进行配置
        CustomTemplateEngine customTemplateEngine = CustomTemplateEngine.getInstance(request);
        // 通过TemplateEngine访问页面
        customTemplateEngine.processTemplate("index", request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

在这个Servlet的doXxx()方法中,我们通过CustomTemplateEngine的getInstance()静态方法获取到了CustomTemplateEngine对象,然后又调用了processsTemplate()方法将响应信息发送到指定的模板文件中展示。

需要特别注意的是,由于我们已经在CustomTemplateEngine的构造方法中设置了模板文件的前缀(/WEB-INF/templates/) 和后缀为(.html),因此我们在调用processTemplate()方法时,第一个形参只需要传入模板文件的名称"index"即可(不要.html后缀),Thymeleaf会自动在"/WEB-INF/templates/"目录下寻找index.html进行解析。

4.编写模板文件

1.在servlet-thymeleaf-project项目的webapp/WEB-INF/templates/目录下,新建一个名为index.html的模板文件,代码如下。

html 复制代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8">
      <title>Index主页</title>
  </head>
  <body>
    <div th:text="访问动态网页Thymeleaf">访问静态页面HTML</div>
  </body>
</html>

2.将项目部署到Tomcat服务器中,然后启动服务器。使用浏览器访问http://localhost:8080/servlet-thymeleaf-project/index,浏览器展示结果如下。

访问动态网页Thymeleaf

3.如果在启动Tomcat服务器时,IDEA控制台输出如下的错误提示日志信息,是因为执行catalina.sh脚本权限被拒绝导致的。

arduino 复制代码
Error running 'Tomcat 10.1.19': Cannot run program "/Users/yuanxin/Documents/ProgramSoftware/apache-tomcat-10.1.19/bin/catalina.sh" (in directory "/Users/yuanxin/Documents/ProgramSoftware/apache-tomcat-10.1.19/bin"): error=13, Permission denied

4.解决"error=13, Permission denied"问题的方法是::进入到Tomcat的bin目录下,执行以下命令。如果Tomcat服务器在启动过程中没有此问题,则忽略[3、4]步骤。

bash 复制代码
chmod a+x catalina.sh

5.总结

本文主要介绍了 Servlet 和 Thymeleaf 的整合过程。首先需下载 Thymeleaf 依赖,可手动或通过坐标添加到项目中。接着配置模板引擎,创建项目并添加相关依赖,利用单例模式在 CustomTemplateEngine 类中设置模板模式、文件路径等信息。然后在 IndexServlet 类的 doGet 等方法中获取 CustomTemplateEngine 实例处理模板文件。最后编写 index.html 模板文件,部署到 Tomcat 服务器并访问。过程中需注意依赖版本匹配及文件权限等问题。

相关推荐
老王不住隔壁、1 小时前
在IDEA中使用通义灵码插件:全面提升开发效率的智能助手
java·ide·intellij-idea
影子信息1 小时前
element 日期时间组件默认显示当前时间
java·前端·javascript
胡尔摩斯.7 小时前
LoadBalancer负载均衡服务调用
java·后端·spring cloud·loadbalancer
编程|诗人7 小时前
T-SQL语言的数据库交互
开发语言·后端·golang
m0_748254478 小时前
springai结合ollama
java
27669582928 小时前
boss直聘 __zp_stoken__ 逆向分析
java·python·node.js·go·boss·boss直聘·__zp_stoken__
m0_748237158 小时前
【Java报错已解决】org.springframework.beans.factory.BeanCreationException
java·开发语言
IT筱筱8 小时前
springboot集成websocket实现实时大量数据,效率性能高
spring boot·后端·websocket
BingoXing8 小时前
Gateway与WebFlux的整合
java·spring boot·spring cloud·gateway·webflux
coding侠客9 小时前
线上工单引发的思考:Spring Boot 中 @Autowired 与 @Resource 的区别
java·spring boot·后端