手写 Spring Boot 嵌入式Tomcat项目开发教学

手写 Spring Boot 嵌入式Tomcat项目开发教学

项目概述

本文将详细介绍如何从零开始开发一个基于Spring Boot和嵌入式Tomcat的Web应用程序。

该项目采用现代化的Java技术栈,展示了Spring Boot的核心特性和最佳实践。

技术栈

  • JDK: 25
  • Spring Boot: 3.x (Spring Framework 6.2.12)
  • 嵌入式Tomcat: 11.0.14
  • 模板引擎: Thymeleaf 3.1.2
  • 构建工具: Maven 3.9.9

开发思路

1. 架构设计思路

本项目采用经典的MVC架构模式,通过Spring Boot的自动配置特性简化开发流程。

选择嵌入式Tomcat作为Web容器,避免了传统部署的复杂性,使应用程序能够以独立JAR包的形式运行。

开发过程中遵循以下设计原则:

  • 约定优于配置:利用Spring Boot的默认配置减少样板代码
  • 分层架构:清晰的Controller层处理HTTP请求
  • 配置外部化:通过Java配置类替代XML配置
  • 模板分离:使用Thymeleaf实现视图与逻辑分离

2. 项目结构设计

复制代码
tomcat-spring/
├── src/main/java/com/lihaozhe/     # Java源码目录
│   ├── Application.java            # 应用程序启动类
│   ├── config/                     # 配置类目录
│   │   ├── SpringConfig.java       # Spring核心配置
│   │   ├── ThymeleafConfig.java    # 模板引擎配置
│   │   └── TomcatConfig.java       # 嵌入式Tomcat配置
│   └── controller/                 # 控制器目录
│       └── HelloController.java    # 请求处理控制器
├── src/main/resources/             # 资源文件目录
│   └── templates/                  # 模板文件目录
│       └── index.html              # 首页模板
└── pom.xml                         # Maven构建配置

开发流程

第一步:项目初始化

首先创建Maven项目,配置基本的构建信息和依赖管理。

在pom.xml中定义项目的基本属性和核心依赖。

Maven配置文件 (pom.xml)
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!--
  开发思路:使用Maven构建Spring Boot项目,配置JDK 25和Spring Boot 3.x依赖
  开发过程:
  1. 设置项目基本信息和编码格式
  2. 配置JDK 25编译环境
  3. 添加Spring Boot核心依赖
  4. 配置嵌入式Tomcat
  5. 集成Thymeleaf模板引擎
  6. 配置构建插件支持可执行JAR
-->
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <!-- Maven模型版本 -->
  <modelVersion>4.0.0</modelVersion>

  <!-- 项目基本信息 -->
  <groupId>com.lihaozhe</groupId>              <!-- 组织标识 -->
  <artifactId>tomcat-spring</artifactId>      <!-- 项目标识 -->
  <version>1.0.0</version>                    <!-- 版本号 -->
  <packaging>jar</packaging>                  <!-- 打包方式 -->

  <!-- 项目属性配置 -->
  <properties>
    <!-- 项目构建编码 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- Maven编译器版本 -->
    <maven.compiler.source>25</maven.compiler.source>
    <maven.compiler.target>25</maven.compiler.target>
    <!-- 项目构建JDK版本 -->
    <maven.compiler.release>25</maven.compiler.release>
  </properties>

  <!-- 依赖管理 -->
  <dependencies>
    <!-- Spring Web MVC核心依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>6.2.12</version>
    </dependency>

    <!-- 嵌入式Tomcat核心依赖 -->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>11.0.14</version>
    </dependency>

    <!-- Thymeleaf模板引擎核心依赖 -->
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf</artifactId>
      <version>3.1.2.RELEASE</version>
    </dependency>

    <!-- Thymeleaf与Spring集成依赖 -->
    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf-spring6</artifactId>
      <version>3.1.2.RELEASE</version>
    </dependency>

    <!-- JSON处理依赖 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.19.2</version>
    </dependency>

    <!-- 日志依赖 -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>2.0.7</version>
    </dependency>

    <!-- 单元测试依赖 -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.11.4</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-engine</artifactId>
      <version>5.11.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
  <!-- 构建配置 -->
  <build>
    <!-- 最终生成的jar包名称 -->
    <finalName>${project.name}-${version}</finalName>

    <!-- Maven插件配置 -->
    <plugins>
      <!-- 1. Maven编译插件:指定JDK版本,解决编译兼容性问题 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.14.1</version>
        <configuration>
          <!-- 源代码兼容的JDK版本 -->
          <source>${maven.compiler.source}</source>
          <!-- 目标字节码兼容的JDK版本 -->
          <target>${maven.compiler.target}</target>
          <!-- 源文件编码格式 -->
          <encoding>${project.build.sourceEncoding}</encoding>
          <!-- 指定JDK编译器路径(如果本地环境变量未配置) -->
          <executable>D:/dev/java/jdk/jdk25/bin/javac.exe</executable>
        </configuration>
      </plugin>

      <!-- 2. JAR打包插件:配置可执行JAR文件,支持java -jar启动 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.5.0</version>
        <configuration>
          <archive>
            <!-- 配置MANIFEST.MF文件 -->
            <manifest>
              <!-- 指定main方法入口类(必须正确配置) -->
              <mainClass>com.lihaozhe.Application</mainClass>
              <!-- 自动添加依赖到类路径(避免ClassNotFoundException) -->
              <addClasspath>true</addClasspath>
              <!-- 依赖库路径前缀 -->
              <classpathPrefix>lib/</classpathPrefix>
            </manifest>
          </archive>
          <!-- 排除不必要的文件 -->
          <excludes>
            <exclude>**/logback.xml</exclude>
            <exclude>**/application*.properties</exclude>
          </excludes>
        </configuration>
      </plugin>

      <!-- 3. 资源文件处理插件:确保templates目录、配置文件正确复制到classpath -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.3.1</version>
        <configuration>
          <!-- 资源文件编码格式 -->
          <encoding>${project.build.sourceEncoding}</encoding>
          <!-- 资源文件包含配置 -->
          <resources>
            <!-- 主资源目录配置 -->
            <resource>
              <directory>src/main/resources</directory>
              <filtering>true</filtering>
              <!-- 包含resources目录下所有文件 -->
              <includes>
                <include>**/*</include>
              </includes>
            </resource>
            <!-- Java目录下的XML文件配置(如MyBatis映射文件) -->
            <resource>
              <directory>src/main/java</directory>
              <filtering>false</filtering>
              <includes>
                <include>**/*.xml</include>
              </includes>
            </resource>
          </resources>
        </configuration>
        <!-- 自定义资源复制阶段 -->
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>process-resources</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <!-- 输出目录 -->
              <outputDirectory>${project.build.outputDirectory}</outputDirectory>
              <resources>
                <resource>
                  <directory>src/main/resources</directory>
                  <filtering>true</filtering>
                  <includes>
                    <include>**/*</include>
                  </includes>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <!-- 4. 依赖复制插件:将项目依赖复制到target/lib目录,方便分发 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>3.9.0</version>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <!-- 依赖复制到target/lib目录 -->
              <outputDirectory>${project.build.directory}/lib</outputDirectory>
              <!-- 排除provided范围的依赖(避免重复) -->
              <excludeScope>provided</excludeScope>
            </configuration>
          </execution>
        </executions>
      </plugin>

    </plugins>

    <!-- 资源目录配置(确保Maven识别templates等目录) -->
    <resources>
      <!-- 主资源目录 -->
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
          <include>**/*</include>
        </includes>
      </resource>
      <!-- Java源码目录中的XML文件 -->
      <resource>
        <directory>src/main/java</directory>
        <filtering>false</filtering>
        <includes>
          <include>**/*.xml</include> <!-- 如果有MyBatis等XML配置文件 -->
        </includes>
      </resource>
    </resources>
  </build>
</project>

第二步:创建应用程序启动类

应用程序启动类是整个项目的入口点,负责初始化Spring容器和启动嵌入式Tomcat服务器。

这里采用编程方式启动Tomcat,而不是使用传统的@SpringBootApplication注解方式,以便更好地理解底层原理。

应用程序启动类 (Application.java)
java 复制代码
package com.lihaozhe;

import com.lihaozhe.config.TomcatConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * <p>Spring Boot嵌入式Tomcat应用程序启动类</p>
 * <p>开发思路:通过编程方式启动Spring容器和嵌入式Tomcat服务器,</p>
 * <p>避免使用@SpringBootApplication注解,更好地理解底层实现原理</p>
 * <p>开发过程:</p>
 * <p>1. 创建Spring应用上下文,加载配置类</p>
 * <p>2. 获取Tomcat配置Bean并启动嵌入式服务器</p>
 * <p>3. 添加JVM关闭钩子,确保服务器优雅关闭</p>
 * <p>4. 处理启动过程中的异常情况</p>
 *
 * @author 李昊哲 李胜龙
 * @version 0.0.1
 */
public class Application {
  /**
   * <p>应用程序主方法,程序入口点</p>
   * <p>开发思路:使用Spring的Java配置方式启动容器,</p>
   * <p>然后手动启动嵌入式Tomcat服务器</p>
   * <p>开发过程:</p>
   * <p>1. 初始化Spring注解配置应用上下文</p>
   * <p>2. 指定基础包路径进行组件扫描</p>
   * <p>3. 刷新上下文以加载所有Bean</p>
   * <p>4. 获取并启动Tomcat服务器</p>
   * <p>5. 添加关闭钩子确保优雅关闭</p>
   *
   * @param args 命令行参数
   */
  public static void main(String[] args) {
    try {
      // 创建Spring注解配置应用上下文
      AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext();
      
      // 设置基础包路径,Spring将扫描这些包下的组件
      context.scan("com.lihaozhe");
      
      // 刷新应用上下文,加载所有配置和Bean
      context.refresh();
      
      // 从Spring容器中获取Tomcat配置Bean
      TomcatConfig tomcatConfig = context.getBean(TomcatConfig.class);
      
      // 启动嵌入式Tomcat服务器
      tomcatConfig.startTomcat();
      
      // 添加JVM关闭钩子,确保服务器能够优雅关闭
      Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        System.out.println("应用程序正在关闭...");
        context.close(); // 关闭Spring容器
      }));
      
      System.out.println("应用程序启动成功!");
      
    } catch (Exception e) {
      // 捕获并处理启动过程中的异常
      System.err.println("应用程序启动失败:" + e.getMessage());
      e.printStackTrace();
      System.exit(1); // 异常退出
    }
  }
}

第三步:配置Spring核心组件

Spring配置类负责定义应用程序的核心配置,包括组件扫描、Bean定义等。

这里使用Java配置方式替代传统的XML配置,提供更好的类型安全和可读性。

Spring核心配置类 (SpringConfig.java)
java 复制代码
package com.lihaozhe.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * <p>Spring核心配置类</p>
 * <p>开发思路:使用Java配置方式替代XML配置,</p>
 * <p>提供类型安全的配置定义和更好的可读性</p>
 * <p>开发过程:</p>
 * <p>1. 使用@Configuration注解标记为配置类</p>
 * <p>2. 配置组件扫描范围,自动发现Spring组件</p>
 * <p>3. 提供默认构造方法,确保Spring能够正确实例化</p>
 *
 * @author 李昊哲 李胜龙
 * @version 0.0.1
 */
// 标记此类为Spring配置类,替代XML配置文件
@Configuration
// 配置组件扫描,自动发现指定包下的Spring组件
@ComponentScan(basePackages = "com.lihaozhe")
public class SpringConfig {
  
  /**
   * <p>默认构造方法</p>
   * <p>开发思路:提供显式的默认构造方法,</p>
   * <p>确保Spring容器能够正确实例化配置类</p>
   */
  public SpringConfig() {
    // 构造方法体,目前为空
    // Spring会自动处理配置类的初始化过程
  }
}

第四步:配置Thymeleaf模板引擎

Thymeleaf是一个现代的服务器端Java模板引擎,能够处理HTML、XML、JavaScript、CSS等文件。

这里需要配置三个核心组件:模板解析器、模板引擎和视图解析器。

Thymeleaf配置类 (ThymeleafConfig.java)
java 复制代码
package com.lihaozhe.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.spring6.view.ThymeleafViewResolver;

/**
 * <p>Thymeleaf模板引擎配置类</p>
 * <p>开发思路:配置Thymeleaf模板引擎的三个核心组件,</p>
 * <p>实现模板文件的解析、处理和视图渲染功能</p>
 * <p>开发过程:</p>
 * <p>1. 配置模板解析器,指定模板文件位置和编码</p>
 * <p>2. 配置模板引擎,集成Spring EL表达式</p>
 * <p>3. 配置视图解析器,处理控制器返回的视图名称</p>
 * <p>4. 设置字符编码和缓存策略</p>
 *
 * @author 李昊哲 李胜龙
 * @version 0.0.1
 */
// 标记此类为Spring配置类
@Configuration
public class ThymeleafConfig {

  /**
   * <p>配置模板解析器Bean</p>
   * <p>开发思路:创建ClassLoaderTemplateResolver,</p>
   * <p>用于从classpath中加载模板文件</p>
   * <p>开发过程:</p>
   * <p>1. 设置模板前缀为templates/目录</p>
   * <p>2. 设置模板后缀为.html</p>
   * <p>3. 配置模板模式为HTML</p>
   * <p>4. 设置字符编码为UTF-8</p>
   * <p>5. 配置缓存策略(开发环境可关闭缓存)</p>
   *
   * @return 配置好的模板解析器实例
   */
  // 声明此方法返回一个Spring管理的Bean
  @Bean
  public ClassLoaderTemplateResolver templateResolver() {
    // 创建类加载器模板解析器
    ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
    
    // 设置模板文件前缀,指向resources/templates目录
    templateResolver.setPrefix("templates/");
    
    // 设置模板文件后缀,支持.html文件
    templateResolver.setSuffix(".html");
    
    // 设置模板模式为HTML,支持HTML5特性
    templateResolver.setTemplateMode(TemplateMode.HTML);
    
    // 设置字符编码为UTF-8,支持中文显示
    templateResolver.setCharacterEncoding("UTF-8");
    
    // 设置缓存为false,开发时便于调试(生产环境建议设为true)
    templateResolver.setCacheable(false);
    
    return templateResolver;
  }

  /**
   * <p>配置模板引擎Bean</p>
   * <p>开发思路:创建SpringTemplateEngine,</p>
   * <p>集成Spring表达式语言和模板解析器</p>
   * <p>开发过程:</p>
   * <p>1. 创建Spring模板引擎实例</p>
   * <p>2. 设置模板解析器</p>
   * <p>3. 启用Spring EL表达式集成</p>
   *
   * @return 配置好的模板引擎实例
   */
  @Bean
  public SpringTemplateEngine templateEngine() {
    // 创建Spring模板引擎
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    
    // 设置模板解析器,用于加载和解析模板文件
    templateEngine.setTemplateResolver(templateResolver());
    
    // 启用Spring EL表达式集成,支持Spring表达式语法
    templateEngine.setEnableSpringELCompiler(true);
    
    return templateEngine;
  }

  /**
   * <p>配置视图解析器Bean</p>
   * <p>开发思路:创建ThymeleafViewResolver,</p>
   * <p>将控制器返回的逻辑视图名解析为实际模板文件</p>
   * <p>开发过程:</p>
   * <p>1. 创建Thymeleaf视图解析器</p>
   * <p>2. 设置模板引擎</p>
   * <p>3. 配置字符编码</p>
   * <p>4. 设置视图名称和内容类型</p>
   *
   * @return 配置好的视图解析器实例
   */
  @Bean
  public ThymeleafViewResolver viewResolver() {
    // 创建Thymeleaf视图解析器
    ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
    
    // 设置模板引擎,用于处理模板渲染
    viewResolver.setTemplateEngine(templateEngine());
    
    // 设置字符编码为UTF-8,确保中文正确显示
    viewResolver.setCharacterEncoding("UTF-8");
    
    // 设置视图名称,支持逻辑视图名解析
    viewResolver.setViewNames(new String[]{"*"});
    
    // 设置内容类型为text/html
    viewResolver.setContentType("text/html");
    
    return viewResolver;
  }
}

第五步:配置嵌入式Tomcat

嵌入式Tomcat配置是本项目的核心部分,负责创建和配置Tomcat服务器实例。

通过编程方式配置Tomcat,可以更好地理解Web服务器的工作原理。

嵌入式Tomcat配置类 (TomcatConfig.java)
java 复制代码
package com.lihaozhe.config;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * <p>嵌入式Tomcat配置类</p>
 * <p>开发思路:通过编程方式配置和启动嵌入式Tomcat服务器,</p>
 * <p>集成Spring MVC的DispatcherServlet,实现Web请求处理</p>
 * <p>开发过程:</p>
 * <p>1. 创建Tomcat实例并配置基本参数</p>
 * <p>2. 创建Spring Web应用上下文</p>
 * <p>3. 配置DispatcherServlet并注册到Tomcat</p>
 * <p>4. 启动Tomcat服务器并处理异常</p>
 *
 * @author 李昊哲 李胜龙
 * @version 0.0.1
 */
public class TomcatConfig {

  /**
   * <p>启动嵌入式Tomcat服务器</p>
   * <p>开发思路:创建Tomcat实例,配置端口和上下文路径,</p>
   * <p>然后集成Spring MVC的DispatcherServlet</p>
   * <p>开发过程:</p>
   * <p>1. 创建Tomcat实例并设置基本参数</p>
   * <p>2. 创建临时目录作为Tomcat工作目录</p>
   * <p>3. 创建Spring Web应用上下文</p>
   * <p>4. 创建并配置DispatcherServlet</p>
   * <p>5. 将DispatcherServlet添加到Tomcat上下文</p>
   * <p>6. 启动Tomcat服务器并等待请求</p>
   */
  public void startTomcat() {
    try {
      // 创建Tomcat实例
      Tomcat tomcat = new Tomcat();
      
      // 设置服务器端口号为8080
      tomcat.setPort(8080);
      
      // 设置主机名为localhost
      tomcat.setHostname("localhost");
      
      // 创建临时目录作为Tomcat工作目录
      String tempDir = System.getProperty("java.io.tmpdir");
      tomcat.setBaseDir(tempDir);
      
      // 创建Tomcat上下文,设置上下文路径为根路径
      Context context = tomcat.addContext("", tempDir);
      
      // 创建Spring Web应用上下文
      org.springframework.web.context.WebApplicationContext webContext = 
        org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
      
      // 如果Web上下文不存在,创建新的应用上下文
      if (webContext == null) {
        // 创建注解配置的Web应用上下文
        org.springframework.web.context.support.AnnotationConfigWebApplicationContext wac = 
          new org.springframework.web.context.support.AnnotationConfigWebApplicationContext();
        
        // 注册配置类
        wac.register(SpringConfig.class, ThymeleafConfig.class);
        
        // 设置上下文配置位置
        wac.setConfigLocation("com.lihaozhe.config");
        
        // 刷新上下文
        wac.refresh();
        
        webContext = wac;
      }
      
      // 创建DispatcherServlet实例
      DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
      
      // 将DispatcherServlet添加到Tomcat上下文
      Tomcat.addServlet(context, "dispatcherServlet", dispatcherServlet);
      
      // 设置Servlet映射,将所有请求映射到DispatcherServlet
      context.addServletMappingDecoded("/", "dispatcherServlet");
      
      // 启动Tomcat服务器
      tomcat.start();
      
      // 输出启动成功信息
      System.out.println("嵌入式Tomcat服务器已启动,访问地址:http://localhost:8080");
      
      // 保持服务器运行,等待请求
      tomcat.getServer().await();
      
    } catch (LifecycleException e) {
      // 捕获Tomcat启动异常
      System.err.println("Tomcat启动失败:" + e.getMessage());
      e.printStackTrace();
      throw new RuntimeException("无法启动嵌入式Tomcat服务器", e);
    }
  }
}

第六步:创建控制器处理请求

控制器是MVC架构中的C部分,负责处理HTTP请求并返回相应的视图。

这里使用Spring MVC的注解来简化控制器开发。

请求处理控制器 (HelloController.java)
java 复制代码
package com.lihaozhe.controller;

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

/**
 * <p>请求处理控制器类</p>
 * <p>开发思路:使用Spring MVC的@Controller注解创建控制器,</p>
 * <p>通过@GetMapping处理HTTP GET请求,返回视图名称</p>
 * <p>开发过程:</p>
 * <p>1. 使用@Controller注解标记为控制器</p>
 * <p>2. 使用@GetMapping映射根路径请求</p>
 * <p>3. 向Model添加数据传递给视图</p>
 * <p>4. 返回逻辑视图名称,由视图解析器解析</p>
 *
 * @author 李昊哲 李胜龙
 * @version 0.0.1
 */
// 标记此类为Spring MVC控制器
@Controller
public class HelloController {

  /**
   * <p>处理根路径请求的方法</p>
   * <p>开发思路:使用@GetMapping注解映射HTTP GET请求,</p>
   * <p>向Model添加数据并返回视图名称</p>
   * <p>开发过程:</p>
   * <p>1. 使用@GetMapping("/")映射根路径</p>
   * <p>2. 通过Model对象传递数据到视图</p>
   * <p>3. 返回逻辑视图名称"index"</p>
   * <p>4. 视图解析器将解析为templates/index.html</p>
   *
   * @param model Spring MVC模型对象,用于传递数据到视图
   * @return 逻辑视图名称,由视图解析器解析为实际模板文件
   */
  // 映射HTTP GET请求到根路径"/"
  @GetMapping("/")
  public String index(Model model) {
    // 向模型添加消息数据,键为"msg",值为欢迎信息
    model.addAttribute("msg", "欢迎使用Spring Boot嵌入式Tomcat项目!");
    
    // 返回逻辑视图名称"index"
    // ThymeleafViewResolver会将其解析为templates/index.html
    return "index";
  }
}

第七步:创建HTML模板文件

Thymeleaf模板文件位于resources/templates目录下,使用HTML5语法和Thymeleaf特有的属性来动态渲染内容。

首页模板 (index.html)
html 复制代码
<!--
  开发思路:使用Thymeleaf模板引擎创建动态HTML页面,
  通过Thymeleaf表达式显示从控制器传递的数据
  开发过程:
  1. 定义HTML5文档结构
  2. 引入Thymeleaf命名空间
  3. 使用Thymeleaf表达式显示动态内容
  4. 添加基本的页面样式
-->
<!DOCTYPE html>
<!-- 引入Thymeleaf命名空间,支持th:前缀的属性 -->
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
  <!-- 字符编码设置,确保中文正确显示 -->
  <meta charset="UTF-8">
  <!-- 视口设置,支持响应式设计 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- 页面标题 -->
  <title>Spring Boot 嵌入式Tomcat 示例</title>
  <!-- 基本样式设置 -->
  <style>
    body {
      font-family: 'Microsoft YaHei', Arial, sans-serif; /* 设置字体 */
      margin: 0; /* 清除默认外边距 */
      padding: 20px; /* 设置内边距 */
      background-color: #f5f5f5; /* 背景色 */
    }
    .container {
      max-width: 800px; /* 最大宽度 */
      margin: 0 auto; /* 居中显示 */
      background-color: white; /* 背景色 */
      padding: 30px; /* 内边距 */
      border-radius: 8px; /* 圆角 */
      box-shadow: 0 2px 10px rgba(0,0,0,0.1); /* 阴影效果 */
    }
    h1 {
      color: #333; /* 标题颜色 */
      text-align: center; /* 居中对齐 */
      margin-bottom: 30px; /* 底部外边距 */
    }
    .message {
      font-size: 18px; /* 字体大小 */
      color: #666; /* 文字颜色 */
      text-align: center; /* 居中对齐 */
      padding: 20px; /* 内边距 */
      background-color: #f8f9fa; /* 背景色 */
      border-radius: 5px; /* 圆角 */
      border-left: 4px solid #007bff; /* 左边框 */
    }
  </style>
</head>
<body>
  <div class="container">
    <!-- 页面标题 -->
    <h1>Spring Boot 嵌入式Tomcat 演示</h1>
    
    <!-- 消息显示区域 -->
    <div class="message">
      <!-- 使用Thymeleaf表达式显示从控制器传递的消息 -->
      <p th:text="${msg}">默认消息</p>
    </div>
    
    <!-- 项目信息 -->
    <div style="margin-top: 30px; text-align: center; color: #999;">
      <p>这是一个基于Spring Boot和嵌入式Tomcat的Web应用程序示例</p>
      <p>技术栈:Spring Boot 3.x + JDK 25 + Thymeleaf</p>
    </div>
  </div>
</body>
</html>

运行和测试

编译和运行项目

项目开发完成后,可以通过以下步骤编译和运行:

  1. 编译项目
bash 复制代码
mvn clean compile
  1. 打包项目
bash 复制代码
mvn clean package
  1. 运行应用程序
bash 复制代码
java -jar target/tomcat-spring-1.0.0.jar
  1. 访问应用程序
    在浏览器中访问:http://localhost:8080

预期结果

成功启动后,浏览器将显示一个包含欢迎信息的页面,页面内容为:"欢迎使用Spring Boot嵌入式Tomcat项目!"

项目特点和优势

技术优势

本项目展示了现代Java Web开发的多个重要特性:

  1. 嵌入式容器:无需外部Tomcat服务器,简化部署流程
  2. Java配置:替代XML配置,提供更好的类型安全性
  3. 注解驱动:使用Spring注解简化开发
  4. 模板引擎:Thymeleaf提供自然的模板语法
  5. Maven构建:标准化的项目构建和依赖管理

学习价值

通过这个项目,开发者可以深入理解:

  • Spring Boot的自动配置原理
  • 嵌入式Web服务器的工作机制
  • MVC架构模式的实现方式
  • 现代Java Web开发的最佳实践

扩展建议

在掌握基础项目后,可以考虑以下扩展方向:

  1. 添加数据库集成:集成JPA和H2/MySQL数据库
  2. 实现RESTful API:添加JSON格式的API接口
  3. 安全认证:集成Spring Security进行用户认证
  4. 前端框架:集成Vue.js或React等现代前端框架
  5. 容器化部署:使用Docker进行容器化部署

总结

本文详细介绍了从零开始开发Spring Boot嵌入式Tomcat项目的完整过程,包括项目架构设计、开发思路、具体实现和运行测试。

通过这个项目,读者可以深入理解现代Java Web开发的核心概念和最佳实践,为进一步学习Spring生态系统打下坚实基础。

项目采用的技术栈都是当前业界主流的选择,具有良好的学习价值和实用性。

通过逐步扩展和完善,可以构建出功能完整的企业级Web应用程序。

相关推荐
麦兜*2 小时前
Redis在Web3中的应用探索:作为链下状态缓存与索引层
java·spring boot·redis·spring cloud·缓存·docker·web3
百***35942 小时前
Spring Boot 中 RabbitMQ 的使用
spring boot·rabbitmq·java-rabbitmq
IT_陈寒2 小时前
React性能优化实战:我用这5个技巧将组件渲染速度提升了70%
前端·人工智能·后端
程序员三明治2 小时前
SpringBoot YAML 配置读取机制 + 数据库自动初始化原理
数据库·spring boot·后端
Victor3563 小时前
Redis(130)Redis的压缩列表(Ziplist)是如何实现的?
后端
q***82913 小时前
Spring Boot 热部署
java·spring boot·后端
Victor3563 小时前
Redis(131)Redis的整数集合(Intset)是如何实现的?
后端
yuuki2332334 小时前
【数据结构】栈
c语言·数据结构·后端
ttthe_MOon5 小时前
动静分离 + 负载均衡:Nginx 与 Tomcat 深度整合实战
nginx·tomcat·负载均衡