首頁 > 軟體

SpringBoot專案打成war和jar的區別說明

2022-06-07 14:07:46

首先給大家來講一個我們遇到的一個奇怪的問題:

1.我的一個springboot專案,用mvn install打包成jar,換一臺有jdk的機器就直接可以用java -jar 專案名.jar的方式執行,沒任何問題,為什麼這裡不需要tomcat也可以執行了?

2.然後我打包成war放進tomcat執行,發現埠號變成tomcat預設的8080(我在server.port中設定埠8090)專案名稱也必須加上了。

也就是說我在原來的機器的IDEA中執行,專案介面地址為 ip:8090/listall,打包放進另一臺機器的tomcat就變成了ip:8080/專案名/listall。這又是為什麼呢?

通過jar執行實際上是啟動了內建的tomcat,所以用的是應用的組態檔中的埠 

直接部署到tomcat之後,內建的tomcat就不會啟用,所以相關設定就以安裝的tomcat為準,與應用的組態檔就沒有關係了

  • 哎,現在學程式設計的基本都不會教歷史了,也沒人有興趣去鑽研。總體來說吧,很多年前,Sun 還在世的那個年代,在度過了早期用 C++寫 Html 解析器的蠻荒時期後,有一批最早的指令碼程式進入了 cgi 時代,此時的 Sun 決定進軍這個領域,為了以示區別並顯得自己高大上,於是研發了 servlet 標準,搞出了最早的 jsp。
  • 並給自己起了個高大上的稱號 JavaEE ( Java 企業級應用標準,我呸,不就是一堆伺服器以 http 提供服務嗎,吹逼)。既然是企業級標準那自然得有自己的伺服器標準。
  • 於是 Servlet 標準誕生,以此標準實現的伺服器稱為 Servle 容器伺服器,Tomcat 就是其中代表,被 Sun 捐獻給了 Apache 基金會,那個時候的 Web 伺服器還是個高大上的概念,當時的 Java Web 程式的標準就是 War 包(其實就是個 Zip 包),這就是 War 包的由來。
  • 後來隨著伺服器領域的屢次進化,人們發現我們為什麼要這麼笨重的 Web 伺服器,還要實現一大堆 Servlet 之外的管理功能,簡化一下抽出核心概念 servlet 不是更好嗎,最早這麼幹的似乎是 Jetty,出現了可以內嵌的 Servelet 伺服器。去掉了一大堆非核心功能。
  • 後來 tomcat 也跟進了,再後來,本來很笨重的傳統 JavaEE 伺服器 Jboss 也搞了個 undertow 來湊熱鬧。正好這個時候微服務的概念興起,“ use Jar,not War ”。要求淘汰傳統 Servlet 伺服器的呼聲就起來了。

jar包和war包的區別

1、war是一個web模組,其中需要包括WEB-INF,是可以直接執行的WEB模組;jar一般只是包括一些class檔案,在宣告了Main_class之後是可以用java命令執行的。

2、war包是做好一個web應用後,通常是網站,打成包部署到容器中;jar包通常是開發時要參照通用類,打成包便於存放管理。

3、war是Sun提出的一種Web應用程式格式,也是許多檔案的一個壓縮包。這個包中的檔案按一定目錄結構來組織;classes目錄下則包含編譯好的Servlet類和Jsp或Servlet所依賴的其它類(如JavaBean)可以打包成jar放到WEB-INF下的lib目錄下。

JAR檔案格式以流行的ZIP檔案格式為基礎。與ZIP檔案不同的是,JAR 檔案不僅用於壓縮和釋出,而且還用於部署和封裝庫、元件和外掛程式,並可被像編譯器和 JVM 這樣的工具直接使用。

【格式特點】

  • 安全性 可以對 JAR 檔案內容加上數位化簽名。這樣,能夠識別簽名的工具就可以有選擇地為您授予軟體安全特權,這是其他檔案做不到的,它還可以檢測程式碼是否被篡改過。
  • 減少下載時間 如果一個 applet 捆綁到一個 JAR 檔案中,那麼瀏覽器就可以在一個 HTTP 事務中下載這個 applet 的類檔案和相關的資源,而不是對每一個檔案開啟一個新連線。
  • 壓縮:JAR 格式允許您壓縮檔案以提高儲存效率。
  • 傳輸平臺擴充套件:Java 擴充套件框架(Java Extensions Framework)提供了向 Java 核心平臺新增功能的方法,這些擴充套件是用 JAR 檔案打包的(Java 3D 和 JavaMail 就是由 Sun 開發的擴充套件例子)。
  • WAR檔案:就是一個Web應用程式,建立WAR檔案,就是把整個Web應用程式(不包括Web應用程式層次結構的根目錄)壓縮起來,指定一個war擴充套件名。

【建立的條件】

  • 需要建立正確的Web應用程式的目錄層次結構。
  • 建立WEB-INF子目錄,並在該目錄下建立classes與lib兩個子目錄。
  • 將Servlet類檔案放到WEB-INFclasses目錄下,將Web應用程式所使用Java類庫檔案(即JAR檔案)放到WEB-INFlib目錄下。
  • 將JSP頁面或靜態HTML頁面放到上下文根路徑下或其子目錄下。
  • 建立META-INF目錄,並在該目錄下建立context.xml檔案。

給大家講講如何將springboot專案打包成jar和war

SpringBoot專案打包成jar很簡單,也是SpringBoot的常用打包格式;本篇部落格將SpringBoot打包成jar和war兩種方式都記錄下來; 

先介紹將SpringBoot打包成jar包的方式:(以下範例是在idea中演示) 

一、打包成jar 

1.先new 一個Spring Starter Project 

這裡注意packaging預設為jar,不用修改.

2.建立完成後專案的pom如下

<?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 http://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>2.1.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
 
	<properties>
		<java.version>1.8</java.version>
	</properties>
 
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</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>

3.打成jar包(通過maven命令的方式)

在Terminal視窗,使用 mvn clean package 命令打包: 

然後在target目錄下就能看到打包好的jar包了

二、打包成war包形式 

1.可以在剛才建立的專案上做改動

首先打包成war需要一個ServletInitializer類,這個類的位置需要和啟動類在同一個檔案下

 (如果一開始選擇war包形式,會自動建立此類) 

2.修改pom.xml 

修改pom.xml的war將原先的jar改為war; 

3.如果我們的SpringBoot是使用html作為前端頁面開發沒有問題

但是如果我們想用jsp開發,這個時候就需要設定一些依賴了:主要是排除SpringBoot的內建Tomcat,新增javax.servlet-api和tomcat-servlet-api(SpringMVC還需要設定字尾); 

最後的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 http://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>2.1.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
 
	<properties>
		<java.version>1.8</java.version>
	</properties>
 
	<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
 
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-servlet-api</artifactId>
            <version>8.0.36</version>
            <scope>provided</scope>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </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>

因為SpringBoot預設推薦的是html,而不是jsp;經過上面的修改就可以使用jsp進行開發了; 

4.打包成war:使用mvn clean package 

如下: 

打包成功後,就可以將war包放在tomcat下的webapps下,然後執行tomcat,啟動專案了;

記錄下來,以後用到的時候看 ^_^; 

(當然了,在建立專案的時候直接選擇package為war,直接就能打成war包了)

當選擇war為打包方式建立專案時,ServletInitializer是預設直接建立的

此時,pom檔案如下

<?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 http://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>2.1.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>
 
	<properties>
		<java.version>1.8</java.version>
	</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-tomcat</artifactId>
			<scope>provided</scope>
		</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>

直接 mvn clean package就能打包成功

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com