引入:
首先小編想分享下一些開發小知識
2000年——手寫servlet/JSP時代
在這個階段中,那時候寫后端代碼,可謂是個麻煩事。
畢竟什么都要自己干
發來的請求都要寫extends HttpServlet的類,手動在web.xml配置
<servlet>、<servlet-mapping>……
JDBC連接、SQL、事務都得自己寫,配置全靠XML。
產生的痛點可太多了,比如xml配置多、代碼臃腫、模塊耦合高。
JSP:全稱JavaServer Pages(Java服務端頁面),它是基于Java的動態網頁技術,允許開發者在HTML頁面中嵌入Java代碼,用于生成動態內容。
2004——Spring FrameWork1.0誕生
此時的框架,引入很多東西,比如
IOC(控制反轉):Bean的創建、依賴由Spring容器負責,代碼里不在到處new
DI(依賴注入):可以用XML、注解(@Atutowired)聲明依賴
AOP(面向切面):用來做事務,日志,權限等橫切邏輯
模塊化:把核心容器拆成spring-core、spring-beans、spring-context、spring-app、spring-tx、spring-jdbc……
這些東西進入進來后,起到了配置簡化的作用,至少有了統一的對象管理和切面支持。
2005——spring web mvc :基于servlet的web框架
引入DispatcherServlet:接收所有的請求并分發
注解驅動:后續版本支持@Controller、@RequestMapping,徹底替代web.xml中<servlet>映射.
視圖解析:整合JSP、FreeMarker、Velocity、Thymeleaf等多種模板。
數據綁定/校驗:支持@RequestParam、@ModelAttribute、@valid等注解
2006——2013:Spring 生態快速擴張
Spring Security:全面安全框架。
Spring Data:簡化JPA、MonggoDB、Redis、Elasticsearch等數據訪問。
Spring Integration / Batch / AMQP:消息、批處理、集成解決方案。
Spring Cloud:進一步演化,提供微服務的配置中心,注冊中心,斷路器、網關等
引入了這么多,但還是有痛點:因為還需要每次都要大量配置XML或JavaConfig,項目的腳手架都要自己搭建。
腳手架:是一個用于快速創建和搭建項目基礎結構的工具或模板。
腳手架工具,目前來說也有是比較多的
比如 Spring Boot Initializr、Yeoman、JHipster……
?2014——Spring Boot 1.0:開箱即用,約定優于配置
自動配置:根據classpath下依賴和定義好的”條件“自動裝配Bean,絕大部分配置”不用寫“
starters:一組起步依賴,比如spring-boot-starter-web(包含SpringMVC、Jackson、Tomcat),
spring-boot-starter-data-jpa。
內嵌容器:默認內嵌Tomcat(可選Jetty、Undertow),打成可執行Jar,運維更簡單
外部配置:統一使用application.properties / application.yml,支持Profile
Actuator:一組監控 / 健康檢查斷點,自動暴露/actuator/heath、/metrics
2016——目前:Spring Boot 2.x/3.x 支持微服務和云原生
Spring Boot 2.x:升級到5.x,支持Reactive WebFlux,Kotlin
Spring Boot 3.x:基于Spring Framework6.x,要求Java17、JakartaEE9
SPring Cloud:與Boot緊密集成,Netfilx OSS,Consul、Nacos、Gateway、Sleuth/Zipkin/Brave分布式鏈路追蹤
CLI / DevTools:命令行工具、熱重載,開發體驗進一步提示。
那么對于以上這些呢,算是小編分享基于Spring開發的時間線。
對于講到Spring而言
它本質上就是個容器,它里面存儲有很多核心組件,這些核心組件負責各自的內容。
MVC:
它是Model View Controller的縮寫,它是軟件工程中的一種軟件架構設計模式
它把軟件系統分為模型、視圖和控制器三個基本部分:
既然MVCVC是一種架構設計模式,那么人人也是可以實現它的,所以SpringMVC就是實現了它
除此之外,SpringMVC還是個web框架。
SpringMVC 結合了自身的特點,做出了些改變,不過整體還是以Model——View——Controller為基準的
這幅圖或許是更加形象些:
剛剛分享到時間線中,提到注解
所以接下來小編分享下SpringMVC的注解吧
注解學習:
跟注解名字相像的,還有一個叫注釋的
注釋:
注釋是寫給程序員看的文字,不會被編譯器或程序執行的,是起到解釋說明作用
作用:
1.幫助別人或自己理解代碼
2.暫時屏蔽部分代碼
3.提供文檔說明
注解:
注解是寫給編譯器或運行時看的結構化信息,它是一種元數據,用來對代碼進行標記,指示行為,甚至自動生成代碼。
作用:
1.在編譯、類加載、運行時被讀取,用來執行特定邏輯
2.框架大量依賴注解來完成”自動配置“和控制反轉
元數據:
元數據是”描述數據的數據“,它本身不是一個業務數據,而是用來描述、標記、解釋其他數據的信息
看起來比較抽象,那么可以舉個這樣的例子
在現實生活中,你拍了一張照片,照片內容是一個風景圖(這個就是一份數據)
當然這個文件中,還有很多內在信息:
- 拍攝時間
- 拍攝地點
- 使用設備
- 分辨率
……
這些信息呢,就是元數據
在代碼中呢,元數據就是來描述代碼的”額外信息“,比如
- 一個類是干啥的
- 一個類是否重寫了父類
- 一個字段是否需要注入
………………
這類信息不是程序主要邏輯,但是框架/工具/編譯器會看這些注解來”做事”。
其實注解,我們開始學習Java語法基礎的時候,也是接觸過的
比如:
Java |
這個注解@Override就是注解,它是表示對父類方法的重寫,編譯器會檢查方法簽名是否是正確
那么注解也是有類型的。
注解類型:
一.運行時注解
這種注解,編譯完后,不僅是存在于.class文件中,程序運行的時候還可以通過反射讀取到
特點:
- 必須用@Retention(RetentionPolicy RUNTIME)中聲明
- 運行時用反射去拿到它的內容
- 常用于Spring、Mybatis、Junit框架做自動處理
二.編譯期注解
這種注解,只會在編譯階段有用,比如校驗、生成代碼,或者 拋出編譯錯誤;但是運行時是看不到的
特點:
- 用@Retention(RetentionPolicy SOURCE)或者@Retention(RetentionPolicy CLASS)聲明
- 靠Annotation Processor(注解處理器),在編譯階段掃描處理
- 常用于Lombok、MapStruct、AutoValue等這類工具
注解還有生效類型,它有Retention策略來決定:
類型 | 用法 | 是否可以通過反射獲取 | 舉例 |
SOURCE | 只存在于源碼中,編譯時丟棄 | 否 | Lombok(自動生成代碼) |
CLASS | 編譯后存在于class文件中,但運行后不保存 | 否 | 常用于框架預編譯掃描 |
RUNTIME | 編譯后保留,并且運行時可反射獲取 | 是 | Spring、Junit中常見注解 |
接下來我們來看看SpringMVC中,有哪些注解吧
一:RestController、RequestMapping
RequestMapping這個注解是用來處理請求映射路徑的,
可以用來類上,此時稱為父路徑,可以用在方法上,此時稱為子路徑
注意:如若沒有加上路徑中,沒有加上/,那么RequestMapping會自動幫我們加上
常用屬性:
屬性 | 說明 | 示例 |
value / path | 請求路徑 | @RequestMapping("/login") |
method | HTTP方法 | RequestMethod.GET,POST,PUT,DELETE |
params | 請求參數過濾 | params="id=10" |
headers | 請求頭過濾 | headers="ContentType=application/json" |
對于RestController而言,這個是復合注解,由@Controller+@ResposeBody而成
Controller注解:
它是用來標識一個類是控制器,當前端請求發送來后,這個類的方法就會接收并處理這些請求
它通常用來返回頁面視圖
比如:
Java |
ResponseBody注解
這個注解就是把方法返回值直接寫到HTTP響應體,不會再找視圖頁面,進行返回
常用于返回JSON、字符串等數據
比如:
Java |
所以對于RestController注解而言,它標注在類上,表示這個類是一個REST風格的控制器,方法返回的是JSON或XML,而不是跳轉頁面。
REST風格控制器
它是一種軟件架構風格,強調資源的唯一標識和標準HTTP方法(GET、PUT、DEPETE、POST等操作)。
所以基于這兩個注解,我們就可以寫上一小段代碼:
Java |
此時我們運行程序后,訪問http:127.0.0.1:8080/user/v2
結果:
值得注意的是RequestMapping中,是默認支持get和post請求的,所以在v1中我這樣寫,意思是僅支持post請求
當然,此時我們要是覺得寫RequestMapping里面的參數太長,代碼還可以這樣寫:
Java |
這兩個注解,其實就是代表僅支持GET和POST請求
此時,我們還可以發現個問題,如若我們每次測試代碼返回結果,都要瀏覽器輸入的話,那么豈不是很麻煩?
所以,小編后面就會使用構造http請求的軟件,這里小編使用的是Postman,文章后面會附上如何下載
剛剛講到的代碼是無參數的,接下來分享是有參數的
單個參數:
typescript |
通過postman構造請求,返回結果:
要值得注意的是,參數名字要一一對應
多個參數:
Java |
構造請求,返回結果:
對象形式:
首先編寫一個對象:
Java |
然后通過idea生成的setter/getter/toString方法,這里就省略了。
Java |
構造請求,返回結果:
為什么傳輸對象可以得到正確數據呢?
這是因為在Springboot中,使用@RequestMapping接收參數時,如果是一個自定義對象,Spring會自動進行參數綁定,將http請求中的查詢參數或表單數據映射到對象的屬性上。
二.@RequestParam
剛剛說到我們請求過來的參數是要一致的,那么這是不是必須的呢?
當然不是,前端傳過來的參數和方法中的參數是可以不一致的,此時,就使用RequestParam注解這個注解用于從
http請求參數中獲取值的,就類似于參數重命名.
參數重命名
比如:
Java |
構造請求返回結果:
那么可以看到username與代碼中的name是對應,userAge和代碼中的age是一一對應。
這個RequesParam注解也是可以設置參數的,此時呢,我在代碼中寫required=f=alse,這個是說明這個age參數不是必傳的,而name參數中,沒有設置,那么它就是默認為true它就是要必傳的,還有,如若這個注解中,什么參數都沒有,此時就可以默認為前端傳來的參數和方法中的參數是一致的。
此時,使用這個參數后,我們還可以傳輸數組內容了
Java |
構造請求返回結果:
當然,數據還可以這樣傳輸:
傳遞集合類:
Java |
構造請求返回結果:
傳遞json對象:
此時前端傳遞json對象,使用的注解,就是RequestBody,這個在一開始講到,這里就不做解釋
Java |
構造請求返回結果
三.@PathVariable
這個注解是將URL路徑中的一部分變量映射到方法參數上
代碼:
Java |
構造請求返回結果
獲取多個參數:
Java |
構造請求返回結果:
當然,我們也可以發現這個注解也是可以參數重命名了,同時我們還得注意的是,參數類型要傳輸正確,比如
id是Integer,name是String,如若反過來傳輸,就會出現以下錯誤:
四.@RequestPart
這個注解是用于從multipart/form-data類型的請求中獲取請求的一部分,通常用于上傳文件+其他字段的組合場景
typescript |
此時呢,一般是要和搭配一個類進行,使用,這個類是MultipartFile
這個是Spring提供的一個接口,用來處理文件上傳的內容
當前端以multipart/form-data方式去提交表單(或者使用FromData)上傳文件的時候,Spring會自動將文件封裝為
MultipartFile對象,交給控制器處理
它有一些常見方法:
方法名 | 作用方法 |
getOriginalFilename() | 獲取原始文件名 |
getContentType() | 獲取文件MIME類型(如image/png) |
getSize() | 獲取文件大小 |
getInputStream() | 獲取輸入流,可用于保存到磁盤 |
getBytes() | 獲取文件的字節數組 |
transferTO(File dest) | 將文件直接保存到目標位置 |
構造請求返回結果
五.操作請求頭
學習前面的一些請求頭后,那么可以對請求頭中一些參數進行操作了,比如cookie ,session
cookie:
cookie是存儲在客戶端(通常是瀏覽器)上的小數據片段,每個cookie都有一個名稱,值以及一些可選的屬性
如過期時間、路徑、域等
作用:
- 存儲用戶的偏好設置(例如語言,主題等)
- 跟蹤用戶的活動
- 維持登錄狀態,通過在客戶端保存會話ID或令牌s
特點:
- 客戶端存儲,可以被用戶查看和修改
- 每次請求都會自動發送到服務器(符合path和domain條件)
- 可以設置HttpOnly標記來防止JavaScript訪問,提高安全性
- 有大小限制(通常為4kb)
Session:
session是一種服務端機制,用來跟蹤用戶狀態。當用戶訪問網站時,服務器會生成一個唯一的會話ID,并將
其存儲在服務器上。通常這個Cookie傳遞給客戶端,以便后續請求能夠識別用戶
- 作用:
存儲敏感信息,這些數據是保存在服務器,不會暴露在客戶端
- 管理會話狀態,如用戶登錄后的行為,購物車內容等
特點:
- 數據存儲在服務器端,更加安全
- 不直接向客戶端暴露具體數據內容,僅通過會話ID關聯
- 生命周期可以與用戶的交互掛鉤,也可以設定固定的超時時間
舉個例子:
當用戶進行首次登錄的時候,服務器收到請求,創建一個SessionID,并通過Cookie返回到客戶端中
在后續的請求中,瀏覽器將自動包含SessionID發送到服務器中,服務器根據這個ID恢復用戶的會話狀態。
那么先來講講這個cookie吧
代碼:
typescript |
這個HttpServletRequest 是Java Web開發常用接口,簡單而言他代表的是客戶端發來的請求
而且也比較萬能,因為它可以得到請求中的很多信息
比如請求方式,請求路徑,請求參數,請求頭,cookie,session……
請求:
不要慌張!我們通過chrome瀏覽器來設置cookie即可
首先點擊:
然后:
再刷新:
服務器中也得到結果:
此時如若出現,chrome瀏覽器無法把cookie帶過去,那么可以使用以下命令回車:
document.cookie = "key=value; path=/; domain=127.0.0.1; SameSite=None; Secure";
在控制臺輸入
當然,這個獲取cookie內容,不止可以使用原生api,還可以使用注解:
這個注解就是:@CookieValue
該注解自動幫你從請求里的cookie中,按照名字,拿出某個值,直接注入你的方法參數中
代碼:
typescript |
結果是差不多,這里不做結果展示。
接下來,講下session
首先分享的是如何設置session:
代碼:
typescript |
生成后,此時呢我們就可以去得到session了
代碼:
typescript |
此時我們訪問SetSession路徑:
可以觀察到,下面的cookie中,是帶有了sessionID了
訪問getSession,就可以獲得結果:
當然,獲取的方法也不是只有這一個,還可以通過HttpSesstion 來獲取
代碼:
Java |
甚至還可以通過注解來獲得:
Java |
六.操作響應內容
之前大多講解的是請求的內容,接下來看看是如何操作這個響應內容的。
1.返回視圖(比如網頁)
用到的注解是controller,這個注解在上面講過了,所以就不做過多講解
typescript |
此時返回視圖的話,那么就是通過Controller注解,而不是RestController
此時,我們Welcome.html是在項目resource/static目錄下
訪問內容:
此時它為什么可以直接展示出網頁內容,大致流程如下:
瀏覽器請求/response/returnHtml
Controller返回字符串“Welome.html”
SpringMVC的視圖解析器會拿到這個字符串,去找該/Welcome.html這個資源
找到了,就會把該/Welcome.html的內容渲染成HTTP響應,瀏覽器自然就會拿到內容。
2.返回內容:
此時呢,使用了Controller后,返回的是視圖了,那么我就是要返回內容呢?
可以使用這個ResponseBody,這個注解,前面也是講過,就不做過多解釋
代碼:
Java |
請求返回結果:
值得注意的是,返回的字符串內容會被瀏覽器自動解析為html內容
如何查看?
刷新頁面:
然后點擊這個后,會出現以下頁面:
這里的text/html說明了,瀏覽器把該內容解析為這樣的類型。
當然返回內容,也是可以返回為html格式內容:
Java |
此時呢,網頁會按照返回內容,進行一級標題渲染。
當然,對于這個ResponseBody來說,它還可以返回json內容
json:
它是一種輕量級的數據交換格式,易于人類閱讀和編寫,同時也是易于機器解析和生成。
基本語法:
- 數據以鍵/值對的方式存儲,例如"name":"John"
- 鍵必須是字符串,使用雙括號括起來,值可以是字符串、數字、對象、數組、布爾值或者null
- 對象使用花括號{}括起來,數組用方括號[]括起來
代碼:
Java |
此時,它是以對象形式返回,那么spring mvc消息轉換器會自動把它轉換為Json格式
postman構造請求返回結果:
此時可以看到返回內容為JSON格式內容了
那么字符串也是可以返回為JSON格式的
代碼:
Java |
通過設置produces參數,就可以返回想要格式,同樣的想返回JSON,那么就寫成application/json,就可以了。
構造請求返回結果
請求頭有HttpServletRequest,那么響應頭中,也有HttpServletResponse,這個也是原生的API,可以說是萬能的。它同樣可以設置/得到響應頭的內容,比如狀態碼、cookie……
那么舉個例子,設置狀態碼
Java |
構造請求,返回結果
同樣的,可以看到即使的得到結果了,也是返回404,這是因為我們手動設置了。
ok,對于springmvc中,一些常見的注解,就分享到這里。
postman下載
postman是一個流行的API開發工具,簡化了構建、測試和文檔化RESTful APIs的過程,對于開發人員還是測試人員等等,它都可以提高工作效率。
它功能,可是有很多的,比如
發送請求、環境和變量管理、自動化測試、監控、Mock Server、文檔生成功能、團隊協作、安全性測試……
這是它的下載地址:
https://www.postman.com/downloads/
下載后,它是一個壓縮包,然后找個地方解壓,運行即可。
接下來介紹一下,基本使用。
簡單使用
首先打開后,可能會讓你進行注冊登錄,那么你就按照提示進行注冊登錄即可
在構建請求區域中,有這些選項,小編這里簡單解釋下:
1.Param
Params這一行指的是“Query Params”部分,它允許你在發送HTTP請求時添加查詢參數。具體來說:
- Key:這是參數的名稱,用來標識這個參數代表什么信息。
- Value:這是與Key對應的值,表示該參數的具體內容。
2.body
Body?標簽頁用于定義請求體的內容,這對于 POST, PUT, PATCH?等需要發送數據到服務器的請求非常重要。它支持多種格式的數據輸入:
- form-data:用于模擬HTML表單提交,通常用于上傳文件或發送鍵值對數據。
- x-www-form-urlencoded:與form-data類似,但是不支持文件上傳。適合發送簡單的鍵值對數據。
- raw:允許你手動輸入請求體內容。支持多種格式,如JSON、XML、Text、JavaScript等。當你需要發送結構化的數據(如JSON對象)時非常有用。
- binary:用于上傳任意類型的文件。例如,上傳圖片、視頻或其他二進制文件。
3.Headers
Headers?標簽頁讓你可以為你的請求添加自定義頭部信息。這可以包括認證令牌(如Bearer Token)、內容類型(Content-Type)、接受類型(Accept)以及其他任何你想要傳遞給服務器的元數據。
4.Authorization
Authorization?標簽頁提供了一個簡單的方式來設置請求的授權方法。你可以選擇不同的授權類型,如No Auth, Basic Auth, Bearer Token, OAuth 1.0, OAuth 2.0等,并根據所選類型填寫相應的憑證。
5.Script
這個標簽允許你在發送請求之前執行一段腳本。這可以用來設置環境變量、發送額外的HTTP請求或者做任何你需要在請求前完成的事情。例如,生成一個動態的時間戳并將其存儲在一個變量中,以便在請求體中使用。
6.Setting
雖然不是直接參與構建請求的部分,但Settings選項提供了配置Postman行為的方式,比如SSL證書驗證、代理設置等
但是還有一個值得注意的是,像前面所說的上傳文件中
你要是覺得英文版,不太好用,那么這里提供國產同類型產品,功能強大,界面友好
下載地址:https://apifox.com/
對于spring mvc注解的分享,小編就分享到這里