Spring Boot - Tomcat 部署



透過使用 Spring Boot 應用程式,我們可以建立一個 war 檔案來部署到 Web 伺服器。在本節中,您將學習如何建立 WAR 檔案並在 Tomcat Web 伺服器中部署 Spring Boot 應用程式。

Spring Boot Servlet 初始化器

傳統的部署方式是使 Spring Boot 應用程式的 @SpringBootApplication 類擴充套件 SpringBootServletInitializer 類。Spring Boot Servlet 初始化器類檔案允許您在使用 Servlet 容器啟動應用程式時對其進行配置。

以下是 JAR 檔案部署的 Spring Boot 應用程式類檔案的程式碼 -

package com.tutorialspoint.demo;

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

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

我們需要擴充套件 SpringBootServletInitializer 類以支援 WAR 檔案部署。以下是 Spring Boot 應用程式類檔案的程式碼 -

package com.tutorialspoint.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class DemoApplication  extends SpringBootServletInitializer {
   @Override
   protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
      return application.sources(DemoApplication.class);
   }
   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}

設定主類

在 Spring Boot 中,我們需要在構建檔案中指定應該啟動的主類。為此,您可以使用以下程式碼片段 -

對於 Maven,在 pom.xml 屬性中新增啟動類,如下所示 -

<start-class>com.tutorialspoint.demo.DemoApplication</start-class>

對於 Gradle,在 build.gradle 中新增主類名稱,如下所示 -

mainClassName="com.tutorialspoint.demo.DemoApplication"

將打包方式從 JAR 更新為 WAR

我們必須使用以下程式碼片段將打包方式從 JAR 更新為 WAR -

對於 Maven,在 pom.xml 中將打包方式新增為 WAR,如下所示 -

<packaging>war</packaging>

對於 Gradle,在 build.gradle 中新增應用程式外掛和 war 外掛,如下所示 -

apply plugin: 'war'
apply plugin: 'application'

現在,讓我們編寫一個簡單的 Rest 端點來返回字串“Hello World from Tomcat”。要編寫 Rest 端點,我們需要將 Spring Boot Web 啟動器依賴項新增到我們的構建檔案中。

對於 Maven,在 pom.xml 中使用以下程式碼新增 Spring Boot 啟動器依賴項 -

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

對於 Gradle,在 build.gradle 中使用以下程式碼新增 Spring Boot 啟動器依賴項 -

dependencies {
   compile('org.springframework.boot:spring-boot-starter-web')
}

現在,在 Spring Boot 應用程式類檔案中使用以下程式碼編寫一個簡單的 Rest 端點 -

package com.tutorialspoint.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication  extends SpringBootServletInitializer {
   @Override
   protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
      return application.sources(DemoApplication.class);
   }
   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
   
   @GetMapping(value = "/")
   public String hello() {
      return "Hello World from Tomcat";
   }
}

打包您的應用程式

現在,使用 Maven 和 Gradle 命令建立 WAR 檔案以部署到 Tomcat 伺服器,如下所示,用於打包您的應用程式 -

對於 Maven,使用命令 mvn package 打包您的應用程式。然後,將建立 WAR 檔案,您可以在 target 目錄中找到它 -

E:\dev\demo>mvn package

您將看到類似於以下的結果

[INFO] Scanning for projects...
[INFO] 
[INFO] [1m----------------------< [0;36mcom.tutorialspoint:demo[0;1m >-----------------------[m
[INFO] [1mBuilding demo 0.0.1-SNAPSHOT[m
[INFO]   from pom.xml
[INFO] [1m--------------------------------[ war ]---------------------------------[m
[INFO] 
[INFO] [1m--- [0;32mresources:3.3.1:resources[m [1m(default-resources)[m @ [36mdemo[0;1m ---[m
[INFO] Copying 1 resource from src\main\resources to target\classes
[INFO] Copying 0 resource from src\main\resources to target\classes
...
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.tutorialspoint.demo.[1mDemoApplicationTests[m
14:41:52.687 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.tutorialspoint.demo.DemoApplicationTests]: DemoApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
14:41:52.817 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.tutorialspoint.demo.DemoApplication for test class com.tutorialspoint.demo.DemoApplicationTests

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.3)

2024-09-03T14:41:53.311+05:30  INFO 7572 --- [demo] [           main] c.t.demo.DemoApplicationTests            : Starting DemoApplicationTests using Java 21.0.3 with PID 7572 (started by Tutorialspoint in E:\Dev\demo)
2024-09-03T14:41:53.313+05:30  INFO 7572 --- [demo] [           main] c.t.demo.DemoApplicationTests            : No active profile set, falling back to 1 default profile: "default"
2024-09-03T14:41:54.704+05:30  INFO 7572 --- [demo] [           main] c.t.demo.DemoApplicationTests            : Started DemoApplicationTests in 1.722 seconds (process running for 3.248)
...
[INFO] Packaging webapp
[INFO] Assembling webapp [demo] in [E:\Dev\demo\target\demo-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [E:\Dev\demo\src\main\webapp]
[INFO] Building war: E:\Dev\demo\target\demo-0.0.1-SNAPSHOT.war
[INFO] 
[INFO] [1m--- [0;32mspring-boot:3.3.3:repackage[m [1m(repackage)[m @ [36mdemo[0;1m ---[m
[INFO] Replacing main artifact E:\Dev\demo\target\demo-0.0.1-SNAPSHOT.war with repackaged archive, adding nested dependencies in BOOT-INF/.
[INFO] The original artifact has been renamed to E:\Dev\demo\target\demo-0.0.1-SNAPSHOT.war.original
[INFO] [1m------------------------------------------------------------------------[m
[INFO] [1;32mBUILD SUCCESS[m
[INFO] [1m------------------------------------------------------------------------[m
[INFO] Total time:  11.809 s
[INFO] Finished at: 2024-09-03T14:41:59+05:30
[INFO] [1m------------------------------------------------------------------------[m

類似地,對於 Gradle,您可以使用命令 gradle clean build 打包您的應用程式。然後,將建立您的 WAR 檔案,您可以在 build/libs 目錄下找到它。

部署到 Tomcat

現在,執行 Tomcat 伺服器,並將 WAR 檔案部署到 webapps 目錄下。觀察此處顯示的螢幕截圖以更好地理解 -

Tomcat Web Application Maneger

webApps Directory

部署成功後,在 Web 瀏覽器中訪問 URL https://:8080/demo-0.0.1-SNAPSHOT/,並觀察輸出將如下面的螢幕截圖所示 -

Successful Deployment Screenshot

以下提供了此目的的完整程式碼。

pom.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>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>3.3.3</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.tutorialspoint</groupId>
      <artifactId>demo</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
      <name>demo</name>
      <description>Demo project for Spring Boot</description>
      <url/>
      <licenses>
         <license/>
      </licenses>
      <developers>
         <developer/>
      </developers>
      <scm>
         <connection/>
         <developerConnection/>
         <tag/>
         <url/>
      </scm>
      <properties>
         <java.version>21</java.version>
         <start-class>com.tutorialspoint.demo.DemoApplication</start-class>
      </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

build.gradle

buildscript {
   ext {
      springBootVersion = '3.3.3'
   }
   repositories {
      mavenCentral()
   }
dependencies {
      classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
   }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'
apply plugin: 'application'

group = 'com.tutorialspoint'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 21
mainClassName = "com.tutorialspoint.demo.DemoApplication"

repositories {
   mavenCentral()
}
dependencies {
   compile('org.springframework.boot:spring-boot-starter-web')
   testCompile('org.springframework.boot:spring-boot-starter-test')
}

以下是主 Spring Boot 應用程式類檔案的程式碼 -

package com.tutorialspoint.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication  extends SpringBootServletInitializer {
   @Override
   protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
      return application.sources(DemoApplication.class);
   }
   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
   
   @GetMapping(value = "/")
   public String hello() {
      return "Hello World from Tomcat";
   }
}
廣告