首页 > 其他分享 >springboot通过tomcat部署项目(包含jar、war两种方式,迄今为止全网最详细!2024更新..建议收藏,教学!万字长文!)

springboot通过tomcat部署项目(包含jar、war两种方式,迄今为止全网最详细!2024更新..建议收藏,教学!万字长文!)

时间:2024-09-22 11:19:50浏览次数:13  
标签:springboot tomcat 项目 部署 boot jar 2024 Tomcat

本博客参考的所有文章均已在结尾声明!!!

在 Spring Boot 项目中,有两种常见的部署方式:
1、使用 Spring Boot 自带的 内置 Tomcat,将项目打包为 jar 并直接运行。
2、使用 外置 Tomcat,将项目打包为 war 并部署到传统的 Tomcat 服务器中。

本文将从这两种方式的基础配置到实际部署,逐步展示 Spring Boot 项目如何通过内置和外置 Tomcat 实现部署。

文章目录

前言

Tomcat简介

Tomcat 是一个非常流行的 轻量级 Web 服务器,它用来运行用 Java 语言编写的 Web 应用程序。Tomcat 就像一个“中间人”或“服务员”,负责接收用户的请求,然后把这些请求转给后台的 Java 程序,处理完后再把结果返回给用户。它和传统的 Web 服务器(比如 Apache HTTP Server、Nginx)不同,Tomcat 主要是为动态 Web 应用服务的。
在这里插入图片描述

起源

Tomcat 的起源可以追溯到 1999 年,由 Apache 软件基金会(一个非盈利组织,负责很多开源项目)开发出来。它最早是 Java Servlet 和 JavaServer Pages (JSP) 的参考实现,也就是一个帮助 Java 程序处理网页请求的标准工具。

Tomcat 之所以得名,是因为 Apache 基金会的成员觉得 “猫科动物”(像老虎、豹等)代表着敏捷、速度和轻巧,和 Tomcat 的特点非常契合。

作用

  • 接收请求:当你打开一个 Java Web 应用(比如在线商店、博客网站),Tomcat 就负责接收你的请求,比如点击商品详情页面。

  • 调用后台程序:Tomcat 会把这个请求交给运行在后台的 Java 程序,让它处理你的请求,比如查询商品信息。

  • 返回网页内容:当后台程序处理好你的请求后,Tomcat 会把结果(比如商品详细信息的页面)返回给你的浏览器,让你能看到网页。

简而言之,Tomcat 是一个 处理 Web 请求和生成动态网页内容的服务器。

优点

  • 免费开源:Tomcat 是免费的,任何人都可以下载、使用,甚至可以改进它的代码。对个人和企业来说,这都非常有吸引力。

  • 轻量级:相比其他复杂的 Java 应用服务器(比如 WebSphere、WebLogic),Tomcat 非常轻量,不需要太多资源,占用的内存和 CPU 比较少。适合一些中小型的 Java Web 项目。

  • 跨平台:不管你用的是 Windows、Mac 还是 Linux,Tomcat 都可以无缝运行。这意味着你可以轻松地在不同的操作系统上搭建 Web 服务。

  • 支持多种 Java 技术:Tomcat 支持 Java Servlet、JSP 等 Java 技术,这些技术是开发 Java Web 应用的基础。

  • 易于集成:它可以很容易地与其他流行的框架和工具(如 Spring Boot、Maven 等)进行集成,使得项目的开发和部署更加方便。

建议

阅读本文之前建议先阅读一下这篇介绍tomcat和servlet的文章 Tomcat工作原理详细介绍,他能让你对自己即将使用的技术有一个整体的、清晰的、初步的认识。(这一篇是我阅读大量文章后筛选出的最好的了。)

我还建议大家先去学习(复习)一下maven:超级详细的 Maven 教程(基础+高级),因为将springboot部署到tomcat时会涉及到大量关于maven中依赖、标签、构建等等知识。(这一篇同样也是我认为介绍maven最好的了。)

一、使用内置 Tomcat 打包为 Jar 部署

1.1 什么是内置 Tomcat 部署?

Spring Boot 默认内置了 Tomcat 服务器,在开发和生产环境中可以直接使用。打包时,将 Tomcat 与项目代码一起打包成一个可执行的 jar 文件,然后通过命令直接运行该 jar 文件来启动服务器。

springboot默认使用tomcat作为内嵌的servlet容器,我们可以由以下步骤验证得知:

首先在自己的springboot项目中的pom.xml文件中找到下面这一条依赖:

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

ctrl+鼠标左键 点击spring-boot-starter-web,如图:
在这里插入图片描述
我们便会进入到spring-boot-starter-web这一jar包的pom文件中
在这里插入图片描述
我们可以看到,spring-boot-starter-web这一jar包已经引入了如下这一条依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-tomcat</artifactId>
	<version>3.1.3</version>
	<scope>compile</scope>
</dependency>

根据依赖的传递性,可知,我们的springboot项目已经默认使用tomcat作为内嵌的servlet容器。

当然我们也可以使用其他容器,比如使用Jetty作为Springboot的内置容器:
在我们的springboot项目中的pom.xml文件做出如下修改:

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

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

在上面的代码中,我们排除了spring-boot-starter-web默认引入的tomcat,而手动引入了jetty。

1.2 Jar 部署的优势

  • 简单直接:无需安装额外的 Tomcat 服务器。
  • 开发方便:在开发阶段可以通过内置的 Tomcat 快速启动和调试。
  • 跨平台性:只需确保系统上有正确版本的 JDK,jar 文件在不同的环境中都可以轻松运行。

1.3 Jar 部署步骤

1.3.1 项目结构

确保项目是标准的 Spring Boot 项目,默认情况下生成的就是 jar 包。项目结构如下:

src
 ├─ main
 │    ├─ java
 │    ├─ resources
 └─ test
pom.xml

1.3.2 确保pom.xml 中的依赖支持打包为 Jar

在 pom.xml 文件中,确保添加了以下插件配置,以支持打包为 jar:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

1.3.3 打包

第一种方式

使用IDEA中的maven管理,运行packsge,打成jar包
在这里插入图片描述

第二种方式

运行以下命令:

mvn clean package

运行后便会打包成jar包

两种方式本质上是一样的。

打包完之后我们项目的target目录下面就会多出现两个包,如图所示:
在这里插入图片描述
其中的.jar包是我们需要的,那么.jar.original包是什么呢?
简单介绍如下,详细可见后面这篇博客 springboot项目用maven打包生成的.jar.original是什么?

.jar.original 是普通jar包,不包含依赖
.jar 是可执行jar包,包含了pom中的所有依赖,可以直接用java -jar命令执行
如果是部署,就用.jar
如果是给别的项目用,就要给.jar.original这个包

1.3.4 运行 Jar 文件

生成的 jar 文件包含了内置的 Tomcat,进入cmd,运行java -jar + jar包名
在这里插入图片描述
在这里插入图片描述
springboot项目已成功启动,我们可以正常访问后端接口。

注:如果想要关闭项目,直接关闭这个cmd黑窗口就可以了

1.3.5 访问接口

使用postman测试接口,成功在这里插入图片描述
在浏览器输入网址访问,成功
在这里插入图片描述

1.3.6 配置端口和其他参数

如果需要自定义 Tomcat 的端口、编码或其他配置,可以在 application.properties 或 application.yml 中进行配置:

server.port=9090
server.servlet.context-path=/myapp

通过这种方式,可以直接修改应用的启动参数和服务器配置。
在这里插入图片描述
clean清除构建结果,compile重新编译,package重新打包

重新运行
在这里插入图片描述
可见,访问接口的方式已经发生了变化。



二、使用外置 Tomcat 打包为 War 部署

2.1 什么是外置 Tomcat 部署?

在一些企业环境中,常常需要将 Spring Boot 项目打包为 war 文件并部署到现有的 Tomcat 服务器中。这种方式比较符合传统的 Java Web 项目部署方式。

2.2 War 部署的优势

兼容传统项目:如果项目需要在同一个 Tomcat 上运行多个应用,使用 war 部署更符合规范。
灵活配置:可以在 Tomcat 服务器层面配置资源池、连接器等,使多个项目共用。

2.3 War 部署步骤

2.3.1 更改入口类

入口类要继承SpringBootServletInitializer并重写configure方法
我们先找到springboot的入口类,在我的项目中位置在这里,大家可以仿照此去找到自己的入口类。(入口类名中一定有“~Application”)springbootstudy\src\main\java\org\example\springbootstudy\SpringbootstudyApplication.java
在这里插入图片描述
大家按照自己的入口类名修改,不要照搬。由于我的项目没用到数据库,所以(exclude = {DataSourceAutoConfiguration.class}) // 暂时禁用数据库禁用了,大家不要在意。

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) // 暂时禁用数据库
public class SpringbootstudyApplication extends SpringBootServletInitializer {
	//继承SpringBootServletInitializer 重写 configure
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder){
		return builder.sources(SpringbootstudyApplication.class);
	}

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

2.3.2 配置pom.xml文件

(1)修改打包方式

先让IDEA知道你这次要打包成war包,在pom.xml中设置打包方式 默认为jar 需要修改为war

<packaging>war</packaging>

如果你在自己的pom.xml文件中找不到标签,那么你可以自己添加,位置可以参考我的
在这里插入图片描述

(2)添加依赖

由于 SpringBootServletInitializer 类需要用到 servlet-api 的相关 jar 包,所以需要添加依赖。
注意这里有
如果你的项目是springboot2.X的,那就使用下面的依赖

 <dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <version>4.0.1</version><!--版本号改成你自己适用的-->
     <scope>provided</scope><!-- 使用 provided 作用域,因为外部容器会提供 Servlet API -->
 </dependency>

如果你的项目是springboot3.X的,那就使用下面的依赖

<dependency>
	<groupId>jakarta.servlet</groupId>
	<artifactId>jakarta.servlet-api</artifactId>
	<version>5.0.0</version>
	<scope>provided</scope> <!-- 使用 provided 作用域,因为外部容器会提供 Servlet API -->
</dependency>

因为 Spring Boot 3.x,需要确保你的所有依赖库(如 Servlet、JPA 等)都使用 Jakarta EE 规范。
而 Spring Boot 2.x,则需要确保你的所有依赖库使用Java EE (javax) 规范。

还有一点需要注意的是我们引入依赖的作用范围是<scope>provided</scope>,这一点后面我们会解释。

(3)移除spring boot内嵌的tomcat

第一种方式(推荐):
在pom.xml文件中添加如下依赖

<!--设置此包运行时不可用-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-tomcat</artifactId>
     <scope>provided</scope>
 </dependency>

<scope>provided</scope>
这个配置项非常重要,它的作用是 指定作用范围。provided 意味着这个依赖会在开发、编译和测试环境中存在,但不会被打包到最终的 war 文件中(因为外部运行环境中已经有Tomcat 服务器,所以不需要在项目中再嵌入)。

第二种移除方式:

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

将上面这段用下面这段替换掉

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<!--排除内置tomcat jar包-->
		<exclusion>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
		</exclusion>
	</exclusions>
</dependency>

注意如果使用了这种方式,那么在开发、测试、编译环境中我们也移除了内置的tomcat服务器,我们的springboot项目就不可以在开发环境(IDEA)中运行了
运行时会提示报错
在这里插入图片描述
这是因为排除内置的 Tomcat 依赖后,Spring Boot 会认为你不再使用嵌入式的 Web容器(比如 Tomcat、Jetty 等),而是打算将应用部署到外部容器(如外部 Tomcat)。这会导致 Spring Boot 不再自动配置嵌入式的 Web 容器,因此你的应用在 IDEA 中无法启动,因为没有配置 ServletWebServerFactory 这个内置的 Servlet 容器工厂。springboot项目在IDEA 中运行时是需要嵌入式的 Web 容器的。

这时我猜细心的同学会问了,我们在(2)中不是引入了servlet-api这个依赖吗,这个的意思难道不是给我们的springboot项目引入容器?
当然不是了,servlet-api 依赖是 Servlet API 的实现,它为 Java Web 应用程序提供了处理 HTTP 请求和响应的核心功能。具体来说,Servlet 是 Java Web 应用程序的基础技术,定义了如何接收 HTTP 请求、处理业务逻辑,并返回 HTTP 响应。总的来说,它并不提供容器,而是仅提供Java Web 应用程序的核心 HTTP 处理能力。

那么我们(2)中引入的依赖为什么必须使用 provided 作用域?
当你将应用部署到外部的容器(如 Tomcat)时,容器自身已经包含了 Servlet API,如果你没有设置 provided,那么你的 WAR 文件里会重复包含这些 API,这可能会导致类冲突或者重复加载的问题。因此,provided 作用域表示依赖在编译时需要,但运行时由外部容器提供。

那么引入(2)这个依赖不是很鸡肋?用第二种移除方式本来在IDEA中就运行不了,只能在外部环境中运行,引入这个依赖的时候还设置provided作用域,打包成war包的时候根本不会把它装进去。

这么想的同学我要夸夸你了,你很细心。但是呢,我们在使用第二种移除方式的时候并不能移除这个依赖,你可以自己试一试,编译时会报错的。
在这里插入图片描述
如果你的项目都没办法编译,那又怎么打包呢????
jakarta.servlet-api 的作用:在编译阶段,它提供了 Servlet 类相关的 API,使得你的项目能够编译通过。

而如果你使用第一种移除方式,那你完全可以不引入(2)中的依赖。因为内置的tomcat服务器中已经包含了Servlet API,所以编译打包一点问题也没有。这也是我推荐第一种移除方式的原因

别嫌我啰嗦,我认为这正是学习、探索的过程,捋清楚思路对自己还是大有脾益的。

(4)一个提醒

在这里插入图片描述

2.3.3 打包

在maven中双击package或者使用mvn clean package命令
在这里插入图片描述
我们可以看到target目录下出现了.war包。

2.3.4 配置本地tomcat

如果电脑现在还没有tomcat的话,参考这篇文章下载一个【Tomcat】史上最全下载、安装配置及使用教程,(2024更新…建议收藏,教学)附Tomcat常见报错解决方法

这里有大坑!!!
tomcat和java-jdk有很严重的兼容问题。
如果你是springboot3+jdk17,那你使用的tomcat应该是10.x以上的。否则在访问springboot项目时会出现spring无法启动的问题,这样访问网页就会出现404

(1)目录介绍

在这里插入图片描述

我们从第一个目录开始逐个了解,只需了解其的基本用处即可。

标签:springboot,tomcat,项目,部署,boot,jar,2024,Tomcat
From: https://blog.csdn.net/m0_73804746/article/details/142306215

相关文章