javascript
Spring Boot Web
一. 概述
下面我們將進入 SpringBoot 基礎階段的學習。 在沒有正式的學習 SpringBoot 之前,我們要先來了解下什么是 Spring 。 我們可以打開 Spring 的官網 ( https://spring.io ) ,去看一下 Spring 的簡介: Spring makes Java simple 。 Spring 的官方提供很多開源的項目,我們可以點擊上面的 projects ,看到 spring 家族旗下的項目, 按照流行程度排序為:- 當前最為流行最受歡迎的Spring Boot,基于Spring? Boot就可以快速方便的構建出一個Spring應用程序。
- Spring? Framework,即Spring框架,是整個Spring家族當中最為底層,最為基礎的一個框架。
- Spring? Data封裝了一系列訪問數據庫的技術。
- Spring Cloud用來構建微服務項目
- 以及Spring Security這樣的安全框架
Spring發展到今天已經形成了一種開發生態圈,Spring提供了若干個子項目,每一個子項目都能夠完成特定的功能來解決特定領域的問題,而我們在開發一個項目的時候,會遇到各種各樣的業務場景,那我們會根據業務開發的需要取選擇對應的技術,從而簡化以及解決對應的業務難題。
而在現在的企業開發當中,開發人員更喜歡偏向于在項目當中選擇Spring家族提供的這一系列的解決方案,為什么呢?
因為這些框架它都屬于Spring體系內的框架,框架之間的整合會非常的容易,甚至可以說是無縫銜接,所以這是當前企業開發當中非常流行,也是非常受歡迎的一種解決方案,被我們親切的稱為Spring全家桶,而Spring家族開發的這么多子項目,其實它都是基于一個基礎框架的,也就是這個Spring? Framework,即Spring框架
?基于Spring Boot就可以快速的來開發一個Spring的應用程序,在SpringBoot的介紹中也看到了,“盡可能快的來構建一個Spring應用”,所以這個Spring? Boot它只是簡化了Spring應用的配置,它的底層還是Spring,它只是簡化了Spring的開發而已。
Spring家族旗下這么多的技術,最基礎、最核心的是 SpringFramework。其他的spring家族的技術,都是基于SpringFramework的,SpringFramework中提供很多實用功能,如:依賴注入、事務管理、web開發支持、數據訪問、消息服務等等。
- 而如果我們在項目中,直接基于SpringFramework進行開發,存在兩個問題:配置繁瑣、入門難度大。
- ?所以基于此呢,spring官方推薦我們從另外一個項目開始學習,那就是目前最火爆的SpringBoot。
- 總結Spring? Boot框架:Spring Boot是Spring家族的一個子項目,可以幫助我們非常快速的構建Spring應用程序,簡化Spring應用程序的配置開發,從而提高開發效率。
- 現在絕大部分的項目,都是基于Spring Boot進行開發的,所以這也是當前企業最為主流的開發方式。
二. Spring Boot Web
- 接下來,我們就直接通過一個SpringBoot的web入門程序,讓大家快速感受一下,基于SpringBoot進行Web開發的便捷性。
- 基于Spring Boot進行Web應用程序開發的便捷性和基本的操作步驟
?1. SpringBootWeb快速入門
?1.1 需求
- 需求:基于SpringBoot的方式開發一個web應用,瀏覽器發起請求/hello后,給瀏覽器返回字符串 “Hello World ~”。
- 當我們在瀏覽器地址欄發起這個請求之后,這個請求要被我們所開發的web應用程序處理,處理完了以后,我們的web應用程序要給瀏覽器來返回一個字符串hello world,然后在瀏覽器當中展示出這個hello world即可,這個就是入門程序的需求。
?1.2 開發步驟
第1步:創建SpringBoot工程項目
第2步:定義HelloController類,添加方法hello,并添加注解
第3步:測試運行
1.2.1 創建SpringBoot工程(需要聯網)
- 基于Spring官方骨架,創建SpringBoot工程。
- 第一步:我們是基于SpringBoot進行web應用程序的開發,此時IDEA會自動連接Spring的官? ? ? ? ? ? ? ? ? 網去創建SpringBoot工程。
-
Group組織名就是域名倒寫? Artifact:模塊名? ?Package name:包名??Artifact / 工件:模塊名
Location:代表的就是我當前所創建出來的Spring Boot工程,最終放在哪個磁盤目錄下呢?
- ?基本信息描述完畢之后,勾選web開發相關依賴。
- ?點擊Finish之后,就會聯網創建這個SpringBoot工程,創建好之后,結構如下:
- 注意:在聯網創建過程中,會下載相關資源(請耐心等待)
- 下面的進度條會一直在加載,這個過程就是在下載Spring Boot進行web開發的相關依賴
pom.xml配置文件信息
- 首先我們先來看一下pom.xml這一份配置文件,在這份配置文件當中,最上面有這么一堆標簽叫做parent,parent這里指定了一個坐標,這個是Spring Boot的父工程,我們把創建的所有的Spring Boot工程,它都需要繼承自這個父工程,這個呢Maven當中叫做繼承,就是來指定一個父工程
- 往下走這里就定義了我們當前項目的坐標信息,而下面這一塊是項目的描述信息,以及我們所選擇的Spring Boot版本所對應的JDK的版本是11版本。
- ?那下面這一塊就是添加了兩個依賴,一個依賴就是Spring Boot進行Web開發的依賴
- 還有一個依賴是進行單元測試的依賴
- 再往下走還有一個插件,這個是Spring Boot項目的一個Maven插件
?目錄信息:
- ?在java目錄下給我們自動創建了一個類,這個類在Spring Boot當中我們稱之為啟動類。
?1.2.2 定義請求處理類?
直接在com.gch下右鍵新建Java類直接新建:controller.HelloController,連包帶類一起創建
- 在com.gch這個包下創建一個子包controller
- ?然后在controller包下新建一個類:HelloController
- 這個類定義好了,要標識它是一個請求處理類,還要指定它要處理的請求是/hello,所以需要 在這個類上加一個注解@RestController,然后在方法上再加上一個注解@RequestMapping,那RequestMapping里面指定的value值是它要處理的請求路徑是什么,是/hello
?1.2.3 運行測試
- 運行SpringBoot自動生成的引導類
?運行結果:
- 運行啟動類,啟動類將我們的web應用啟動起來之后,它會自動占用一個端口號8080。
?打開瀏覽器,輸入 http://localhost:8080/hello
- http代表的是請求的協議? ?localhost代表的是我們要訪問的是當前本機的服務
- 8080代表的是我們訪問的端口? ? Tomcat服務器的端口號就是8080
- /hello代表的就是訪問的資源
- 打開瀏覽器,訪問8080端口的/hello這個資源,那此時就會請求到剛才我們所編寫的請求處理方法
- 當我們在瀏覽器地址欄發起這個請求之后,這個請求要被我們所開發的服務器端的web應用程序處理,處理完了以后,我們服務器端的web應用程序要給瀏覽器來返回一個字符串hello world,然后在瀏覽器當中展示出這個hello world即可,這個就是入門程序的需求。
三. Http協議
3.1 HTTP-概述
在入門程序中,我們在瀏覽器發起了一個請求,請求路徑是localhost:8080/hello,回車之后,我們就訪問到了服務器端的web應用程序,并且,也拿到了服務器端返回回來的數據:Hello? World~。
那其實呢,我們在瀏覽器地址欄輸入這個地址之后,瀏覽器默認會自動的在請求路徑前面加上一個協議:http://,這個我們就稱之為HTTP協議。
HTTP:Hyper Text Transfer Protocol(超文本傳輸協議),規定了瀏覽器與服務器之間數據傳輸? ? ? ? ? ? ? ? ?的規則。
?2.1.1 介紹
?什么是數據傳輸的規則:
說白了就是客戶端瀏覽器與服務器之間進行數據交互的數據格式
- 比如我們客戶端瀏覽器,將來要請求服務器來獲取一些數據,那此時瀏覽器就需要給服務器端發送請求,那服務器端再給瀏覽器響應對應的數據,那么瀏覽器給服務器發送請求是需要攜帶請求數據,最起碼你得告訴服務器,我需要什么東西,那服務器接收到這些請求數據之后,服務器就需要來解析這些數據,而服務器要想成功的解析數據,前提服務器得知道瀏覽器給我發送過來的請求數據長什么樣子,具體的數據格式是什么樣子的,每一項代表什么含義,否則,服務器端無法解析。
- 也就是說,瀏覽器和服務器之間,它們得建立好一個約定,我瀏覽器發送數據,將來就長這個樣子,我就給你按照這個格式來寫,服務器端你就按照這個格式解析就可以了,那這樣呢,服務器端就能夠知道客戶端瀏覽器的意圖了,那么同理,服務器端處理完請求之后,需要給客戶端瀏覽器來響應一些數據,那響應的數據返回給客戶端瀏覽器之后,瀏覽器也是需要來解析這些數據的,而瀏覽器要想成功解析,就必須得要求服務器按照一定的格式來返回這些數據,而這些數據傳輸的格式,都是在HTTP協議當中規定的,所以我們所說的這個http就是數據傳輸的規則,數據傳輸的格式,主要就包括兩個方面,一個是請求數據的格式,一個是響應數據的格式。
- http是互聯網上應用最為廣泛的一種網絡協議
- http協議要求:瀏覽器在向服務器發送請求數據時,或是服務器在向瀏覽器發送響應數據? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?時,都必須按照固定的格式進行數據傳輸
- Request? Headers:請求的數據? Response? Headers:響應的數據? ?View? parsed:原始的數據格式
- 原始的數據格式其實就是一個文本字符串,將來瀏覽器發送請求的時候,就會將這么一個文本字符串帶到服務器端去,而這個格式是非常固定的。
?瀏覽器向服務器進行請求時:
- 服務器按照固定的格式進行解析
- 請求數據格式:
- 第一行叫做請求行,里面就指定了請求的方式是GET請求、請求的資源路徑以及請求的協議。
- 第一行之后的這些被稱之為請求頭,而每一個請求頭它的格式:前面是請求頭的名字,后面是請求頭的值,請求頭的名字和請求頭的值中間用:分隔開。
- 這個格式是固定的,將來瀏覽器就可以把這個數據發送到服務端,服務端就可以根據這個固定的格式來解析數據。
- 瀏覽器按照固定的格式進行解析
- 響應數據格式:
- 將來服務器端給瀏覽器響應的就是這樣一個文本字符串,瀏覽器只需要按照指定的格式來解析就可以了。
?所以,我們學習HTTP主要就是學習請求和響應數據的具體格式內容。
?3.2 特點
?我們剛才初步認識了HTTP協議,那么我們在看看HTTP協議有哪些特點:
- 基于TCP協議: 面向連接,安全
TCP是一種面向連接的(建立連接之前是需要經過三次握手)、可靠的、基于字節流的傳輸層
通信協議,在數據傳輸方面更安全 TCP它是一種面向連接的安全的協議,也就是說,每一次請求之前,要先進行三次握手,連接完了之后確定雙方都有收發能力了,我再來傳輸數據,這樣呢不容易數據包,更加安全。- 基于請求-響應模型的: 一次請求對應一次響應(先請求后響應)
- HTTP協議是無狀態協議: 對于數據 / 事務處理沒有記憶能力。每次請求-響應都是獨立的。
- 缺點: 多次請求間不能共享數據(多次請求間不能進行數據的共享)
- 優點: 速度快
正是因為多次請求之間不會進行數據共享,后一次請求不會記錄前一次請求的數據,這也就意味著它的速度會更快一些,而多次請求之間不能共享數據,那也就意味著有很多的功能,HTTP協議就實現不了。
就比如我這里有一個后臺管理系統,在這個后臺管理系統的業務需求當中就要求,必須用戶登錄之后才可以訪問系統當中的數據,當我點擊登錄按鈕執行登陸操作的時候,有一次請求響應,登陸完成之后進入系統,這一次請求響應結束,接下來我再來訪問課程管理的數據,而當我點擊課程管理的時候,它就要去訪問課程的數據,而在訪問課程數據的時候,我是需要知道這個用戶到底有沒有登錄的,如果登錄成功,我再給它返回課程的數據,如果沒有登錄成功,是不允許訪問課程的數據,由于登錄請求和訪問課程管理數據的這個請求是兩次不同的請求,而HTTP協議它又是無狀態的,在兩次請求之間,它是沒辦法共享數據的,那這也就造成了這一次課程管理的請求,它并不知道上一次用戶是否登錄成功了,那這就出現問題了。解決方案:web會話技術。
請求之間無法共享數據會引發的問題:- 如:京東購物。加入購物車和去購物車結算是兩次請求
- 由于HTTP協議的無狀態特性,加入購物車請求響應結束后,并未記錄加入購物車是何 商品
- 發起去購物車結算的請求后,因為無法獲取哪些商品加入了購物車,會導致此次請求無 法正確展示數據
剛才提到HTTP協議是規定了請求和響應數據的格式,那具體的格式是什么呢?
重點:請求數據的格式和響應數據的格式
3.2 HTTP-請求協議
瀏覽器和服務器是按照HTTP協議進行數據通信的。?
HTTP協議又分為:請求協議和響應協議
-
請求協議:瀏覽器將數據以請求格式發送到服務器
-
包括:請求行、請求頭 、請求體
-
-
響應協議:服務器將數據以響應格式返回給瀏覽器
-
包括:響應行 、響應頭 、響應體
-
在HTTP1.1版本中,瀏覽器訪問服務器的幾種方式:
| GET | 獲取資源。 向特定的資源發出請求。例:百度安全驗證 |
| POST | 傳輸實體主體。 向指定資源提交數據進行處理請求(例:上傳文件),數據被包含在請求體中。 |
| OPTIONS | 返回服務器針對特定資源所支持的HTTP請求方式。 因為并不是所有的服務器都支持規定的方法,為了安全有些服務器可能會禁止掉一些方法,例如:DELETE、PUT等。那么OPTIONS就是用來詢問服務器支持的方法。 |
| HEAD | 獲得報文首部。 HEAD方法類似GET方法,但是不同的是HEAD方法不要求返回數據。通常用于確認URI的有效性及資源更新時間等。 |
| PUT | 傳輸文件。 PUT方法用來傳輸文件。類似FTP協議,文件內容包含在請求報文的實體中,然后請求保存到URL指定的服務器位置。 |
| DELETE | 刪除文件。 請求服務器刪除Request-URI所標識的資源 |
| TRACE | 追蹤路徑。 回顯服務器收到的請求,主要用于測試或診斷 |
| CONNECT | 要求用隧道協議連接代理。 HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器 |
在我們實際應用中常用的也就是 :GET、POST
- 請求協議指的就是請求數據的格式
- 那這個請求數據的格式,我們剛才已經看到了,就是一些文本字符串
- 請求數據的格式分為三個部分:請求行、請求頭、請求體?
- 第一個部分就是這個GET,POST,這是第一部分,那這個指的是請求方式。這個請求方式,之前在講解HTML的form表單的時候說過,這個表單的方式有兩種,一種是GET,一種是POST,那其實GET和POST就是HTTP的請求方式,當然HTTP的請求方式有很多,我們這里先知道GET和POST就可以了。
- /請求路徑?請求參數? ? ? ?請求路徑和請求參數之間使用?連接
- 請求參數格式:參數名=參數值&參數名=參數值
- 請求方式之后,有一個空格,空格后面就是第二個部分的內容:/brand/findAll請求路徑后面跟上的是請求的參數,那這個部分指的是請求的資源路徑。
- 那資源路徑之后,又有一個空格,空格之后就是第三個部分:HTTP/1.1,這個代表的是協議以及協議的版本。
- 以上就是請求數據格式的第一部分請求行的格式。
? ? ? 2. 請求數據格式的第二個部分:請求頭(第二行開始,格式:key=value)
- 請求頭指的就是從第二行開始,一直到后面的這一部分數據,請求頭的格式是key:value形式的鍵值對。
- 前面的這個部分指的是請求頭的名字,后面這部分指的是請求頭對應的值,中間使用:進行分隔。
- http是個無狀態的協議,所以在請求頭設置瀏覽器的一些自身信息和想要響應的形式。這樣服務器在收到信息后,就可以知道是誰,想干什么了
- 在請求頭當中攜帶了很多的信息,包括瀏覽器的版本,請求的主機地址,請求的數據格式等等。
- ?接下來,介紹一下常見的請求頭它所代表的含義:
??
- Host:localhost:8080,代表的是我們要請求的是當前本機的8080端口的服務。
- User-Agent:代表的是瀏覽器的版本,也就是說客戶端瀏覽器它得告訴服務器端,我當前請求用的是哪一個瀏覽器,我的版本是什么。
- 那告訴服務器端這個瀏覽器版本有什么用呢?
- 這個地方一般會用于瀏覽器的兼容性處理。
- 因為市面上有很多的瀏覽器,而不同的瀏覽器它們的內核是有差異的,這就造成了同一段程序在不同的瀏覽器解析出來,它的效果是不一樣的,這個呢,我們稱之為瀏覽器的兼容性問題。
- 那我們在服務器端,如果拿到了客戶端瀏覽器的版本,我就可以有針對性的進行處理,從而保證不論你采用什么樣的瀏覽器,你最終訪問到的效果都是一樣的,那這就是解決瀏覽器的兼容性問題。
- 而解決瀏覽器的兼容性問題,最核心的就是我們在服務器端得拿到瀏覽器的版本。
- Accept:text/*:表示我瀏覽器期望接收的是一個文本;image/*:表示我瀏覽器期望接收的是一個圖片
- Accept-Language:zh-CN,比如我這里傳遞了一個zh-CN,這就相當于我瀏覽器告訴服務器端,我瀏覽器期望接收到的是簡體中文的語言。
- Accept-Encoding:gzip,代表我瀏覽器可以接收gzip的壓縮格式
- Content-Type:application/json,就代表請求體的格式,它是一個json格式的數據。
- Content-Length:161,就代表這個請求體的大小是161個字節。
?3. 請求數據格式的第三個部分:請求體(POST請求,存放請求參數)
- 請求體是POST請求特有的一個組成部分,POST請求最后一個部分就是請求體,它是用來存放請求參數的。
- 在這個請求體和請求行之間是有一個空行存在的,通過一個空行將這兩部分分離開來- - (作用:用于標記請求頭結束)。
- 而在POST請求里面,它就把請求參數放在了請求體這個位置,那之前我們在講解HTML的form表單的時候,我們就介紹過,GET請求和POST請求的區別,在這里我們再來回顧一下:
- 在GET請求當中,請求參數是在請求行當中的,具體的表現形式,就是在請求路徑之后跟上?key=value,如果有多個參數,后面再跟上&key=value的形式。而GET請求它是沒有請求體的,并且它的請求大小是有限制的。
- 而如果是POST請求,它的請求參數是攜帶在請求體當中,它的請求大小沒有限制。
一. GET方式的請求協議:
請求行 :HTTP請求中的第一行數據。由:請求方式、資源路徑、協議/版本組成(之間使用空格分隔)
-
請求方式:GET
-
資源路徑:/brand/findAll?name=OPPO&status=1
-
請求路徑:/brand/findAll
-
請求參數:name=OPPO&status=1
-
請求參數是以key=value形式出現
-
多個請求參數之間使用&連接
-
-
請求路徑和請求參數之間使用?連接
-
-
協議/版本:HTTP/1.1
請求頭 :第二行開始,上圖黃色部分內容就是請求頭。格式為key: value形式
常見的HTTP請求頭有:
- Host: 表示請求的主機名
- User-Agent: 瀏覽器版本。 例如:Chrome瀏覽器的標識類似Mozilla/5.0 ...Chrome/79 ,IE瀏覽器的標識類似Mozilla/5.0 (Windows NT ...)like Gecko
- Accept:表示瀏覽器能接收的資源類型,如text/*,image/*或者*/*表示所有;
- Accept-Language:表示瀏覽器偏好的語言,服務器可以據此返回不同語言的網頁;
- Accept-Encoding:表示瀏覽器可以支持的壓縮類型,例如gzip, deflate等。
- Content-Type:請求主體的數據類型
- Content-Length:數據主體的大小(單位:字節)
-
http是個無狀態的協議,所以在請求頭設置瀏覽器的一些自身信息和想要響應的形式。這樣服務器在收到信息后,就可以知道是誰,想干什么了
舉例說明:服務器端可以根據請求頭中的內容來獲取客戶端瀏覽器的相關信息,有了這些信息服務器端就可以處理不同的業務需求。
比如:
-
不同瀏覽器解析HTML和CSS標簽的結果會有不一致,所以就會導致相同的代碼在不同的瀏覽器會出現不同的效果
-
服務器端根據客戶端請求頭中的數據獲取到客戶端的瀏覽器類型,就可以根據不同的瀏覽器設置不同的代碼來達到一致的效果(這就是我們常說的瀏覽器兼容問題)
請求體 :存儲請求參數
-
GET請求的請求參數在請求行中,故不需要設置請求體
二. POST方式的請求協議:
-
請求行(以上圖中紅色部分):包含請求方式、資源路徑、協議/版本
-
請求方式:POST
-
資源路徑:/brand
-
協議/版本:HTTP/1.1
-
-
請求頭(以上圖中黃色部分)
-
請求體(以上圖中綠色部分) :存儲請求參數
-
請求體和請求頭之間是有一個空行隔開(作用:用于標記請求頭結束)
-
GET請求和POST請求的區別:
| 請求參數 | 請求參數在請求行中。 例:/brand/findAll?name=OPPO&status=1 | 請求參數在請求體中 |
| 請求參數長度 | 請求參數長度有限制(瀏覽器不同限制也不同) | 請求參數長度沒有限制 |
| 安全性 | 安全性低。原因:請求參數暴露在瀏覽器地址欄中。 | 安全性相對高 |
演示:GET請求與POST請求? ? ? ?
- 在IDEA當中,我已經準備好了一個HTML頁面
- 在這個HTML頁面當中我定義了兩個form表單,在這個form表單當中的表單項是完全一致的,只是它們的提交方式不一樣,第一個表單它的提交方式是GET,第二個表單提交方式是POST
點擊IDEA的懸浮工具條,然后選擇一個瀏覽器打開?
GET方式提交:
POST方式提交:
3.3?HTTP-響應協議
?3.1 格式介紹
- HTTP協議響應數據的格式
- 響應協議也就是響應數據的格式,響應數據的格式與請求數據的格式非常的類似,也是由三個部分組成的,分別是響應行、響應頭和響應體
- 與HTTP的請求一樣,HTTP響應的數據也分為3部分:響應行、響應頭 、響應體
- 響應行也是由三個部分組成的,響應行由"協議及協議的版本"、"響應狀態碼"、"狀態碼描述"組成。
-
協議/版本:HTTP/1.1
-
第一個部分就是HTTP/1.1,這個代表的是就是協議以及協議的版本
-
響應狀態碼:200
-
第一部分之后有一個空格,空格之后是第二部分是一個數字,這個數字就代表了響應的狀態碼,這個狀態碼指的就是服務器端要告訴客戶端這次響應到底是怎么樣的狀態,是成功還是失敗。這里所出現的200代表的是成功。
-
狀態碼描述:OK
-
第二個部分之后又有一個空格,空格之后是第三個部分,它是一個英文,這個英文就是用來描述前面的狀態碼的。這里的OK就代表成功了。
-
其實這個狀態碼有很多,而我們一般會將其分為五類,分別從100多一直到500多。
2.?響應頭(以上圖中黃色部分):響應數據的第二行開始。格式為key:value形式。
- 響應頭當中是用來描述響應信息的。
- 從第二行開始以key:value形式體現出來的這一塊數據都是響應頭的數據。
3.?響應體(以上圖中綠色部分): 響應數據的最后一部分。存儲響應的數據
- 響應體當中存儲的就是響應回來的數據,響應體是整個響應數據的最后一個部分
- 跟請求體一樣,響應體和響應頭之間有一個空行隔開(作用:用于標記響應頭結束)
- 響應體我們一般也叫響應正文,這個里面所展示的這個JSON格式的數據,就是響應正文的內容,將來,瀏覽器解析到這些數據之后,再配合著前端的代碼實現,就可以展示對應的頁面信息了。
響應狀態碼:
- 響應狀態碼的分類:
- 在HTTP協議當中,響應的狀態碼大概分為這么五類,分別是100多,200多,一直到500多。
- 100多代表的是響應中,它是一個臨時狀態碼。
- 其實就是說,服務器端已經接收到了客戶端的請求,但是服務器端發現客戶端的請求還沒有發送完整,服務器端先給客戶端一個臨時的響應狀態碼,告訴客戶端你要繼續發送完整的請求數據。
- 這一類的響應狀態碼比較少見,大家在后面的項目當中可能會用到一個技術叫Web Socket,拿使用Web Socket的時候,就會發現它的狀態碼就是100多,是101,目前這個了解即可。
- 200多這個狀態碼代表的是成功,成功的意思是這一次的請求響應已經被成功的接收和處理了,已經處理完成了,那我給你返回一個200多。客戶端發送了請求,服務端已經成功的處理了這個請求并且響應也是成功的,那這個是我們最想看到的狀態碼,這也是每一個軟件工程開發師的幸運數字。
- 那這個狀態碼是我們開發人員最希望看到的一個狀態碼。
- 第三類是300多,300多代表的是重定向的狀態碼。
- 所謂重定向它的含義指的是這里呢,有一個客戶端瀏覽器,客戶端瀏覽器要去訪問A服務器上的資源,接下來呢,它要發送請求到A服務器,但是這個資源已經被我挪到了另外一個服務器B服務器當中,那么此時A服務器就可以給瀏覽器返回一個狀態碼就是300多,并且呢,在這個狀態碼里面告訴瀏覽器,你再去訪問B服務器上的這個資源就可以,那此時瀏覽器拿到響應回來的狀態碼以及響應回來的這個路徑之后,接下來,瀏覽器會自動的再去請求B服務器上的資源,從而獲得響應數據,那這個過程是瀏覽器自動完成的,那這個呢,我們就稱之為重定向。
- 當然,在這幅圖當中A和B有可能是同一臺服務器,只是資源的位置不用而已。
- 接下來的這兩類狀態碼400多和500多比較常見也比較重要,它們都代表的是錯誤的情況。
- 那將來我們在開發項目的時候,只有你知道了這些狀態碼的含義,你才能夠知道具體的錯誤到底出現在什么位置,我們才能夠知道怎么來解決這些錯誤。
- 400多代表的是客戶端錯誤。
- 客戶端錯誤指的是處理發生錯誤了,責任是在客戶端的。比如,我們隨便在瀏覽器的地址欄當中輸入一個地址,那這個地址如果不存在,此時就會出現一個狀態碼,那就是400多,那一旦出現了400多的狀態碼,那我就知道,這個問題是在客戶端。那我就需要去檢查客戶端的請求路徑,檢查客戶端的請求參數,然后把它們改正確就可以了。
- 最后一類500多指的是服務器錯誤。
- 服務器錯誤代表的是如果將來處理發生錯誤,責任在服務端。
- 那比如我們在訪問我們的Web程序時,由于代碼的Bug出現了一個異常,那此時就會響應一個500多的狀態碼,那看到這個狀態碼之后,我們就知道這個問題出現在服務端,那我需要去檢查一下服務端的日志,去看一下是否有異常產生,然后再依據異常的堆棧信息,把對應的異常解決掉就可以了。
常見的響應狀態碼:
- 200它表示的是OK,OK它所代表的意思就是客戶端發送了請求,服務端已經成功的處理了這個請求并且響應也是成功的。這個是我們最想看到的狀態碼,也是每一個軟件開發工程師的幸運數字。
- 302表示的是重定向,就是說客戶端瀏覽器請求的資源已經轉移到了另外一個位置,那這個位置,我服務器可以通過一個響應頭Location返回給你,告訴你對應的URL地址,那么瀏覽器拿到這個狀態碼之后并且拿到了響應頭Location,它就會自動的去請求Location這個響應頭對應的請求路徑,然后再去獲取這個頁面的資源,那這就是302狀態碼。
- 還有一個304狀態碼,它的意思就是服務器端要告訴客戶端你所請求的這個資源自上次請求以后我服務器端并沒有做任何的修改,你可以直接去訪問你自己的本地緩存就可以了,就不用再訪問服務器再來獲取這個資源了。那此時,服務器的壓力就減輕了,因為就不存在數據傳輸的過程了。
- 400表示的是Bad? Request,Bad Request指的就是客戶端的請求語法有錯誤,不能被服務器理解,比如客戶端所傳遞的請求參數,格式錯誤等等,那此時就會出現400這個狀態碼。
- 403指的是服務器端接收到了請求,但是拒絕訪問,一般來說,都是因為你沒有權限來訪問這個資源,那我就給你返回一個403。
- 404是我們將來所見到的客戶端最為常見的一個錯誤,叫Not? Found,Not? Found代表的是你所請求的資源不存在,那一般呢,就是我們輸入的請求路徑是有誤的,或者網站資源被刪除了,找不到這個網站資源了。
- 405代表的是請求方式有誤。比如,我們服務端所提供的這個請求的資源,它要求必須以GET方式來請求,而我們使用的是POST的請求方式,那這個時候,就會出現405,請求的方法不被允許。
- 428代表的是服務器要求有條件的請求。那這個指的意思就是說當我們去訪問一個服務端的資源的時候,它要求我們必須要攜帶對應的一些條件,比如我們要攜帶一些特定的請求頭,如果我攜帶了這個請求頭,它才允許我訪問,那如果我們沒有攜帶,那此時就會返回一個狀態碼428。
- 429代表的是請求數太多了,那這個代表的是用戶在指定的時間內發送了太多的請求,造成服務器的壓力比較大,那這個時候就會出現429。429可以配合這一個響應頭叫做Retry-After,代表的是在多長時間以后,我們可以再次嘗試請求。
- 431指的就是我們所請求的數據,請求頭的字段太多了,服務器不愿意處理。
- 500也是我們將來見的比較多的一類狀態碼,如果是5開頭的,都代表的是服務器端異常。
- 500代表的是服務器端發生了不可預期的錯誤,一般都是服務器端拋異常了,那如果出現500,我們就需要去看一下服務器端的日志,來看一下在控制臺當中是不是出現了異常,如果出現異常,我們需要去解決這個問題。500代表的是服務器端發生了異常或者是錯誤。
- 503指的是服務器尚未準備好處理請求。比如我們服務器剛剛啟動,我還沒有啟動完成呢,瀏覽器發起了一個請求,那此時就會報出503。
| 200 | OK | 客戶端請求成功,即處理成功,這是我們最想看到的狀態碼 |
| 302 | Found | 指示所請求的資源已移動到由Location響應頭給定的 URL,瀏覽器會自動重新訪問到這個頁面 |
| 304 | Not Modified | 告訴客戶端,你請求的資源至上次取得后,服務端并未更改,你直接用你本地緩存吧。隱式重定向 |
| 400 | Bad Request | 客戶端請求有語法錯誤,不能被服務器所理解 |
| 403 | Forbidden | 服務器收到請求,但是拒絕提供服務,比如:沒有權限訪問相關資源 |
| 404 | Not Found | 請求資源不存在,一般是URL輸入有誤,或者網站資源被刪除了 |
| 405 | Method Not Allowed | 請求方式有誤,比如應該用GET請求方式的資源,用了POST |
| 428 | Precondition Required | 服務器要求有條件的請求,告訴客戶端要想訪問該資源,必須攜帶特定的請求頭 |
| 429 | Too Many Requests | 指示用戶在給定時間內發送了太多請求(“限速”),配合 Retry-After(多長時間后可以請求)響應頭一起使用 |
| 431 | Request Header Fields Too Large | 請求頭太大,服務器不愿意處理請求,因為它的頭部字段太大。請求可以在減少請求頭域的大小后重新提交。 |
| 500 | Internal Server Error | 服務器發生不可預期的錯誤。服務器出異常了,趕緊看日志去吧 |
| 503 | Service Unavailable | 服務器尚未準備好處理請求,服務器剛剛啟動,還未初始化好 |
?常見的HTTP響應頭有:
- Content-Type:表示該響應內容的類型。比如我們這里響應了一個內容,它的類型是一個json,所以在Content-Type這一欄顯示的就是:application/json。那將來客戶端瀏覽器獲取到這個數據之后,它就會按照json格式的數據來處理。
- Content-Length:指的是響應內容的長度(單位是字節)。那通過這個響應頭客戶端就能知道服務器給我響應回來的數據它的長度到底是多長。
- Content-Encoding:表示該響應數據的壓縮算法。比如我們這里設置了一個gzip,那這就表示服務器端在傳輸數據的時候采用的是gziip的算法進行壓縮的,那將來客戶端拿到數據之后也要使用gzip的算法來進行解壓縮。
- Cache-Control:指示客戶端應如何緩存。緩存的意思就是你第一次在訪問的時候你訪問服務器,把服務器返回的數據,緩存在瀏覽器本地,下一次你再來訪問的時候,你就不用再請求服務器了,你直接讀本地的文件,這樣速度會更快一些,而且也會降低服務器端的壓力。在設置客戶端如何緩存的時候,可以設置這么一塊信息,叫做max-age=300,這就代表我緩存這一塊的這個數據,最多只存儲300秒,300秒之后緩存的數據就沒了,那我就需要再次請求服務器端再來獲取數據。
- Set-Cookie: 告訴瀏覽器為當前頁面所在的域設置cookie。什么是cookie在后面介紹Web會話技術的時候再來詳細介紹。(cookie是指儲存在用戶本地終端上的數據,是基于網絡瀏覽器的一種機制,它的作用是存儲用戶的上網行為信息,以便在以后的網頁瀏覽中給予相應的個性化服務。)
?3.4?HTTP-協議解析
- HTTP協議的解析就是根據HTTP的請求格式來解析請求數據以及響應數據。
- 解析HTTP協議,其實分為兩個部分,一個是客戶端,一個是服務端。
- 而對于客戶端瀏覽器,各大廠商已經給我們提供了,它里面就內置了解析HTTP協議的程序,我們不需要操作。我們作為一名服務端開發工程師,需要做的就是在服務器端通過Java程序來接收客戶端瀏覽器發起的請求,并獲取請求數據,然后,再參照HTTP協議的請求數據格式對請求數據進行解析,然后還需要參照HTTP協議的響應數據格式給瀏覽器再響應對應的數據。
- 剛才我們提到在瀏覽器里面就已經內置了解析HTTP協議的程序,那瀏覽器獲取到響應回來的數據之后會自動解析,從而完成這一次請求響應。
- 接下來我們就需要去研究一下,在服務器端我們怎么樣解析HTTP的數據,并且給瀏覽器響應數據。
- 其實按照我們目前的知識儲備,我們是可以把這個程序寫出來的。在TCP網絡編程這樣的技術中,我們可以通過Socket以及Server Socket就可以寫出一個服務器端的程序了,然后瀏覽器就可以來發送HTTP的請求,我們就可以通過ServerSocket來接收客戶端發起的這個請求,那接收到請求之后,我們就可以獲取到這個請求的數據,那讀取出來的請求數據呢就是一些字符串,而這個字符串,它的格式我們前面學過是固定的,那我們就可以按照字符串的組成規則來解析它,同理,我們也可以通過ServerSocket來獲取到輸出流,然后就可以按照HTTP響應數據的格式給瀏覽器,響應一個固定格式的字符串,那這樣呢,就完成了一次網絡請求。
- 服務器是可以使用java完成編寫,是可以接受頁面發送的請求和響應數據給前端瀏覽器的,而在開發中真正用到的Web服務器,我們不會自己寫的,都是使用目前比較流行的web服務器。如:Tomcat
- 我們所開發的Web程序要解析HTTP協議,那其他所有的Web項目要開發,也都需要去解析HTTP協議,而HTTP協議它是標準的,是統一固定的,所以這部分解析HTTP協議的代碼也是非常通用的,所以有很多公司已經把這些代碼都已經寫好了,而且還封裝到了一個軟件程序當中供我們來使用,而這個軟件就是我們所說的Web服務器。
- Web服務器軟件有很多,其中最為流行也是最受歡迎的就是阿帕奇基金會下的Tomcat服務器。
- 這些Web服務器本質上就是一個軟件程序,就是對HTTP協議進行了封裝,使程序員不必直接對HTTP協議進行操作,因為畢竟是比較繁瑣的,也就是說,如果有了這些Web服務器,HTTP協議的解析和處理的代碼,我們都不用去做了,開發人員只需要關注我們當前項目的業務實現邏輯就可以了,這樣使得Web程序的開發更加簡單,更加便捷,也更加高效。
3. Web服務器-Tomcat
- Web服務器的主要功能就是提供網上信息的瀏覽服務。也就是說我們只需要在我們的服務器當中安裝一個Web服務器,比如當前最為流行的Tomcat,然后我們就可以將我們開發好的Web應用部署在Tomcat服務器上,然后啟動服務器之后,我們就可以打開瀏覽器直接訪問到部署在Tomcat服務器上的應用程序。
- 基于Tomcat服務器訪問到的頁面資源。
3.1 Tomcat簡介
- ?官網:Apache Tomcat? - Welcome!
- ?開源指的是開放源代碼,源代碼開放出來我們就可以根據自己的需求來定制Tomcat服務器。
- Java語言的三大分支:JavaSE:Java標準版? ?JavaME:Java小型版? JavaEE:Java企業版
- JavaME指的是Java小型版,Java小型版主要是用來開發一些嵌入式設備的應用,比如像手機,車載設備等等。
- JavaEE:Java企業版,它是一系列企業級開發技術的總和,也就是說我們將來開發一個企業級的項目,?會用到很多的技術,而這些技術都有著對應的規范和標準,這些技術規范總結起來一共有13項,我們通稱為JavaEE規范。
- 而在這些規范當中,有很多的規范其實已經過時了,比如像EJB,現在已經被Spring替代了,還有像Servlet,JSP這樣的技術,現在基于Servlet進行項目開發基本上已經很少了,取而代之的是一些基于Servet封裝的高級框架。
- JavaEE的13項技術規范里面Tomcat只支持Servlet和JSP等少量的JavaEE規范。
- 而正是因為Tomcat只支持少量的JavaEE規范,所以呢它是一個輕量級的Web服務器。
- 不像WebLogic、WebSphere這些服務器,它支持全部的JavaEE規范,所以它們是重量級的Web服務器。
- 正是因為Tomcat是一個輕量級的Web服務器,所以Tomcat我們也稱之為Web容器。
- Servlet它是基于Servlet規范開發出來的一種Web資源,這個Servlet程序它是不能夠獨立運行的,它是需要依賴于支持Servlet規范的這種Web服務器才可以運行,那Tomcat就支持了Servlet規范,所以這個Tomcat我們也稱為Servlet容器。
?小結:
1. Web服務器
- Web服務器本質上就是一個軟件程序,就是對HTTP協議進行了封裝,使程序員不必直接對HTTP協議進行操作,因為畢竟是比較繁瑣的,也就是說,如果有了這些Web服務器,HTTP協議的解析和處理的代碼,我們都不用去做了,開發人員只需要關注我們當前項目的業務實現邏輯就可以了,這樣使得Web程序的開發更加簡單,更加便捷,也更加高效。
- Web服務器可以用來部署我們開發好的Web項目,對外提供網上信息瀏覽服務。
2. Tomcat
- Tomcat是一個輕量級的Web服務器,支持Servlet以及JSP等少量的JavaEE規范。
- 所以Tomcat也被稱為Web容器或者Servelet容器。
?3.2?Tomcat服務器的基本使用
基本使用就包括Tomcat的下載,安裝,卸載,啟動,訪問,部署等一系列的操作。
1. 下載
- 直接從官方網站下載:Apache Tomcat? - Apache Tomcat 9 Software Downloads
-
Tomcat軟件類型說明:
- tar.gz文件,是linux和mac操作系統下的壓縮版本
- zip文件,是window操作系統下壓縮版本(我們選擇zip文件)
2. 安裝與卸載
安裝: Tomcat是綠色版,直接解壓即安裝
- 注意,Tomcat在解壓縮的時候,解壓所在的目錄最好解壓到一個不包含中文和空格的目錄,因為后期在部署項目的時候,如果路徑有中文或者空格可能會導致程序部署失敗。
打開apache-tomcat-9.0.27目錄就能看到如下目錄結構,每個目錄中包含的內容需要認識下
?
bin:目錄下有兩類文件,一種是以".bat"結尾的,是Windows系統的可執行文件,一種是? ? ? ? ? ? ? ? ? ? ? 以".sh"結尾的,是Linux系統的可執行文件。
- bin目錄存放的是可執行文件,conf存放的是Tomcat當中的配置文件。
- 第三個lib目錄存放的是Tomcat依賴的jar包,因為Tomcat是基于Java語言開發的。
- logs目錄存放的是日志文件,Tomcat運行所產生的一些日志,都存放在logs這個文件夾下。
- webapps存放的是應用程序的發布目錄,也就是說我們要部署應用程序,就需要將應用程序放在webapps這個目錄下。webapps:就是以后項目部署的目錄
- work是Tomcat的工作目錄
卸載:卸載比較簡單,可以直接刪除目錄即可
3. 啟動與關閉
啟動:
啟動Tomcat只需要訪問bin目錄下的一個腳本文件startup.bat,直接雙擊該腳本就可以將Tomcat啟動起來。
- 我們可以看到Tomcat在運行過程當中輸出的一些日志,在輸出的日志里面中文亂碼了,這hi是因為在Tomcat默認的配置當中,控制臺輸出日志這一塊兒的編碼它默認是UTF-8,我們把這個選項改為GBK就可以了。
- ?將編碼從默認的UTF-8改為GBK
- Tomcat運行起來之后默認占用的端口是8080,8080是Tomcat默認的端口號
?
- 訪問這一臺Tomcat
- Tomcat的默認端口為8080,所以在瀏覽器的地址欄輸入:http://127.0.0.1:8080?即可訪問tomcat服務器
- 127.0.0.1 也可以使用localhost代替。如:http://localhost:8080
- 能看到以上圖片(Tomcat服務器的歡迎頁面)中Apache Tomcat的內容就說明Tomcat已經啟動成功
?注意: tomcat服務器啟動后,黑窗口不會關閉,只要黑窗口不關閉,就證明tomcat服務器正在運行
?關閉: 關閉有三種方式
1、強制關閉:直接×掉Tomcat運行窗口(不建議)
?2、正常關閉:bin\shutdown.bat
3、正常關閉:在Tomcat啟動窗口中按下 Ctrl+C
-
說明:如果按下Ctrl+C沒有反映,可以多按幾次
4.?常見問題
問題1:Tomcat啟動時,窗口一閃而過
-
檢查JAVA_HOME環境變量是否正確配置
?問題2:端口號沖突
- BindException:端口號沖突
- 在一臺主機上端口號是不能重復的
- 發生問題的原因:Tomcat使用的端口被占用了。
-
解決方案:換Tomcat端口號
-
要想修改Tomcat啟動的端口號,需要修改 conf/server.xml文件
-
注: HTTP協議默認端口號為80,如果將Tomcat端口號改為80,則將來訪問Tomcat時,將不? ? ? ? 用輸入端口號。
?Tomcat 部署項目: 將項目放置到 webapps 目錄下, 即部署完成
?演示所部署的應用:
3.3 入門程序解析
基于本次的核心技術點SpringBoot快速入門案例進行分析。
3.3.1 Spring官方骨架
- 之前我們在IDEA創建的SpringBoot入門案例,是基于Spring官方提供的骨架實現的。
- Spring官方骨架,可以理解為Spring官方為程序員提供一個搭建項目的模板。
Spring Initializrhttps://start.spring.io/
- ?我們可以通過訪問:Spring Initializr,進入到官方骨架頁面
- ?這個是我們進行Web程序開發所需要的依賴,我們開發Web應用,只需要這一個依賴就可以? 了。
?Spring官方生成的SpringBoot項目,怎么使用呢?
-
解壓縮后,就會得到一個SpringBoot項目工程
- ?打開pom.xml文件,我們可以看到springboot項目中引入了web依賴和test依賴
- 另一個test依賴是我們創建Spring Boot項目它默認給我們加入進來的依賴,這個依賴是單元測試所需要的依賴。
?結論:不論使用IDEA創建SpringBoot項目,還是直接在官方網站利用骨架生成SpringBoot項? ? ? ? ? ? ? ? ? 目,項目的結構和pom.xml文件中內容是相似的。
- 我們在IDEA當中去創建這個Spring Boot項目的時候,其實就是關聯的是官方的這個模板,所 以,我們在創建Spring Boot項目的時候,它是需要聯網的,
3.3.2 起步依賴
- 在我們之前講解的SpringBoot快速入門案例中,同樣也引用了:web依賴和test依賴
- spring-boot-starter-web和spring-boot-starter-test,在SpringBoot中又稱為:起步依賴
- 而在SpringBoot的項目中,有很多的起步依賴,他們有一個共同的特征:就是以"spring-boot-starter-"作為開頭。
- 在以后大家遇到spring-boot-starter-xxx這類的依賴,都為起步依賴。
- 而每一個起步依賴都用于開發特定的功能。
- 起步依賴是一種比較特殊的Maven依賴,它利用了Maven當中的依賴傳遞特性,把開發某一個功能所需要的常見依賴就聚合在了一起。
- 比如web依賴它就把Web開發所需要的一些常見的依賴都聚合在了這一個模塊當中,那我們進行Web開發,我們只需要引入這一個web開發的起步依賴就可以了,通過Maven的依賴傳遞就會將其他的依賴全部傳遞下來。
- 起步依賴的好處:? 簡化依賴配置,利用Maven當中的依賴傳遞特性,引入這一個依賴,就相? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?當于引入了這一塊兒業務開發所需要的全部依賴
起步依賴有什么特殊之處呢,這里我們以入門案例中引入的起步依賴做為講解:
-
spring-boot-starter-web:包含了web應用開發所需要的常見依賴
-
spring-boot-starter-test:包含了單元測試所需要的常見依賴
- spring-boot-starter-web內部把關于Web開發所有的依賴都已經導入并且指定了版本,只需引入 spring-boot-starter-web 依賴就可以實現Web開發的需要的功能
- Spring的官方提供了很多現成的starter(起步依賴),我們在開發相關應用時,只需要引入對應的starter即可。
- 在Spring的官方當中,提供了很多的起步依賴,比如后面要用到的aop,redis等...
- 官方地址:https://docs.spring.io/spring-boot/docs/2.7.2/reference/htmlsingle/#using.build-systems.starters
Spring Boot Reference Documentationhttps://docs.spring.io/spring-boot/docs/2.7.2/reference/htmlsingle/#web
- 每一個起步依賴,都用于開發一個特定的功能。
- 舉例:當我們開發中需要使用redis數據庫時,只需要在SpringBoot項目中,引入:spring-? ? ? ? ? ? ? ? ? ?boot-starter-redis ,即可導入redis開發所需要的依賴。
3.3.2 SpringBoot父工程
- 在我們之前開發的SpringBoot入門案例中,?我們所創建出來的這個Spring Boot工程,在pom.xml當中我們通過maven引入這個起步依賴的時候,它是沒有加入version版本號的,是沒有指定具體的依賴版本號的。
為什么沒有指定<version>版本號,可以正常使用呢?
- 因為每一個SpringBoot工程 / 項目,都有一個統一的父工程,也就是上面所配置的這個parent,這個parent它是Spring Boot的父工程,所有的Spring Boot工程都需要繼承自這樣的一個父工程,而在Spring Boot工程當中,這些起步依賴的版本都在這個父工程當中已經進行了統一管理。
- 父工程指定了版本號后,就會自動的引入和所指定版本對應的起步依賴。
- 依賴的版本號,在父工程中進行統一管理。
- 比如你選擇了Spring Boot的版本是2.7.4,并且已經配置好了這個父工程,那Spring Boot就會自動的給你引入與這個2.7.4版本對應的起步依賴。
3.3.3 內嵌Tomcat
- 我們進行web程序的開發,只需要引入web開發的起步依賴就可以了。
- 而當我們引入了web開發的起步依賴之后,我們會看到,通過Maven的依賴傳遞,傳遞了這么一項依賴,叫spring-boot-starter-tomcat,這個是Tomcat的相關依賴,那也就是說,在Spring Boot Web開發環境當中,它已經將Tomcat集成進來(也就是引入spring-boot-starter-web起步依賴 ),其內部已經集成了內置了Tomcat服務器。
-
我們可以通過IDEA開發工具右側的maven面板中,就可以看到當前工程引入的依賴。其中已經將Tomcat的相關依賴傳遞下來了,也就是說在SpringBoot中可以直接使用Tomcat服務器。
- 所以,我們在運行SpringBoot的引導類 / 啟動類時(運行main方法),啟動Spring Boot項目的過程當中,它會自動地將內部的這個Tomcat服務器啟動起來,并且占用了Tomcat默認端口號8080,而這個Tomcat并不是我們剛才所安裝的Web的Tomcat,而是spring-boot-starter-web的開發環境內置的這個Tomcat,我們也叫內嵌的Tomcat服務器。
- 我們會看到命令行輸出的日志,其中占用8080端口的就是Tomcat。
- 那這個服務器啟動起來之后,我們就可以打開瀏覽器,在瀏覽器地址欄輸入localhost:8080/hello,回車之后我們就訪問到了這臺內嵌的Tomcat,并且訪問到了部署在里面的這個web程序,最終就拿到了響應的結果
- 在開發當中基本上都是基于Spring Boot來進行Web程序的開發,所以我們剛才所獨立安裝的這個Tomcat服務器就會很少使用了,我們以后基本上用的都是Spring Boot當中內置的Tomcat服務器。
總結
以上是生活随笔為你收集整理的Spring Boot Web的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么有的人中级职称是评审,有的是考试呢
- 下一篇: 翻译 | 《JavaScript Eve