文章目錄
- 代碼總結
- 初始化--@RestController、@RequestMapping
- 傳遞參數
- 單參數
- 多參數
- 傳遞對象
- 后端參數重命名(后端參數映射)--@RequestParam
- 必傳參數
- 設置非必傳參數
- 傳遞數組
- 傳遞集合
- 傳遞JSON數據
- JSON語法
- JSON格式轉換
- JSON優點
- 傳遞JSON對象
- 獲取URL中參數--@PathVariable
- 傳遞文件--@RequestPart
- 獲取HTTP請求中的Header信息--@RequestHeader
- 傳統獲取header
- 簡潔獲取Header
- Cookie與Session
- Cookie
- Cookie機制
- Session
- Cookie與Session交互
- 常見面試題
- Cookie 和 Session 的區別
- Session產生的SessionId放在Cookie里面,如果用戶把Cookie禁止掉,是不是Session也不能用了呢?
- 獲取Cookie與session
- 獲取Cookie
- 傳統獲取Cookie
- 簡潔獲取Cookie
- 獲取Session
- 設置Session
- 傳統獲取Session
- 簡潔獲取Session
代碼總結
初始化–@RestController、@RequestMapping
@RestController:該注解用于標記一個類作為RESTful Web 服務的控制器
@RequestMapping(“/request”):該注解用于將 HTTP 請求映射到對應的控制器方法上,將特定的 URL 路徑(如 “/request”)映射到控制器類或方法。
url路徑前加上"/"
建議類路徑與方法路徑一起使用
RequestMapping即支持get請求,也支持post請求,默認是get請求
@RequestMapping("/request")
@RestController//標記一個類作為RESTful Web 服務的控制器
public class RequestController {//后面這個是url,建立客戶端與服務器之間的連接//可以修飾類,也可以修飾方法(修飾類時,訪問路徑: 類路徑+訪問路徑)@RequestMapping("/hello")public String say(){return "Hello Spring MVC";}
}
傳遞參數
單參數
- 傳遞單參數時,需要保持方法的參數變量的名稱與請求的名稱一致。
- 使用基礎類型與包裝類型作為接收參數時,當請求為空時,包裝類型只為null,基礎類型會報出500錯誤,通常情況下只使用包裝類型。
@RequestMapping("/r1")public String r1(String name){return "接收到參數: "+name;}@RequestMapping("/r2")public String r2(Integer age){return "接收到參數: "+age;}@RequestMapping("/r3")public String r3(int age){return "接收到參數: "+age;}
多參數
當有多個參數時,前后端進?參數匹配時,是以參數的名稱進?匹配的,因此參數的位置是不影響后端獲取參數的結果。
@RequestMapping("/r4")public String r4(String name,Integer age){return "接收到參數name="+name+" age="+age;}
傳遞對象
- 如果參數?較多時,?法聲明就需要有很多形參,并且后續每次新增?個參數,也需要修改?法聲明,不妨把這些參數封裝為?個對象。 Spring
- 根據參數名稱?動綁定到對象的各個屬性上,如果某個屬性未傳遞,則賦值為null(基本類型在創建對象時賦值為默認初識值,?如int類型的屬性,會被賦值為0,此時不會報錯)
@RequestMapping("/r5")public String r5(Student student){return "接收到參數student: "+student;}
后端參數重命名(后端參數映射)–@RequestParam
必傳參數
@RequestParam:某些特殊的情況下,前端傳遞的參數key和后端接收的key可以不?致,?如前端傳遞了?個 name 給后端,而后端是使? username 字段來接收,這樣就會出現參數接收不到的情況,如果出現這種情況,使? @RequestParam 來重命名前后端的參數值。
@RequestMapping("/r6")public String r6(@RequestParam("name") String username){//接收前段的name賦值給后端的usernamereturn "接收到參數student: "+username;}
使? @RequestParam 進?參數重命名時,請求參數只能和 @RequestParam 聲明的名稱一致,才能進?參數綁定和賦值。
使? @RequestParam 進?參數重命名時,參數就變成了必傳參數,也就是接收到為 null ,直接報錯。
設置非必傳參數
@RequestMapping("/r7")public String r7(@RequestParam(value = "name",required = false) String username){return "接收到參數student: "+username;}
傳遞數組
Spring MVC可以?動綁定數組參數的賦值。
@RequestMapping("/r8")public String r8(String[] arrays){return "arrays: "+ Arrays.toString(arrays);}
傳遞集合
集合參數:和數組類似,同?個請求參數名有為多個,且需要使? @RequestParam 綁定參數關系。
這是因為后端不能直接接收集合這樣的參數數組,所以先通過數組接收數據,再通過 @RequestParam 映射。
@RequestMapping("/r9")public String r9(@RequestParam List<String> list){return "arrays: "+ list;}
傳遞JSON數據
JSON:JavaScriptObjectNotation 【JavaScript 對象表示法】
JSON是?種輕量級的數據交互格式,它基于ECMAScript(歐洲計算機協會制定的js規范)的?個?集,采?完全獨?于編程語?的?本格式來存儲和表示數據。
JSON是?種數據格式,有??的格式和語法,使??本表示?個對象或數組的信息,因此JSON本質是字符串。
JSON語法
數據在鍵值對(Key/Value) 中
數據由逗號 , 分隔
對象? {} 表?
數組? [] 表?
值可以為對象,也可以為數組,數組中可以包含多個對象
示例:
{"name":"zhangsan","id":1111,"age":22
}
JSON格式轉換
工具:https://www.bejson.com/,可以對JSON字符串進行壓縮整理。
將上述JSON字符串進行壓縮:
{"name":"zhangsan","age":12,"id":1111}
JSON本質上是?個字符串,通過?本來存儲和描述數據。
Spring MVC框架也集成了JSON的轉換?具,可以直接使用,來完成JSON字符串和Java對象的互轉。
public static void main(String[] args) throws JsonProcessingException {ObjectMapper objectMapper = new ObjectMapper();String jsonstr = "{\"name\":\"zhangsan\",\"age\":12,\"id\":1111}";//json字符串轉對象,使用該方法時,類中必須要有無參數的構造函數Student student = objectMapper.readValue(jsonstr,Student.class);System.out.println(student);//對象轉json字符串String s= objectMapper.writeValueAsString(student);System.out.println(s);}
JSON優點
- 簡單易用:語法簡單,易于理解和編寫,可以快速地進?數據交換
- 跨平臺?持:JSON可以被多種編程語?解析和生成,可以在不同的平臺和語?之間進?數據交換和傳輸
- 輕量級:相較于XML格式,JSON數據格式更加輕量級,傳輸數據時占用寬帶較小,可以提?數據傳輸速度
- 易于擴展:JSON的數據結構靈活,支持嵌套對象和數組等復雜的數據結構,便于擴展和使用
- 安全性:JSON數據格式是?種純文本格式,不包含可執?代碼,不會執?惡意代碼,因此具有較?的安全性
傳遞JSON對象
接收JSON對象,需要使? @RequestBody 注解。
RequestBody:請求正?,意思是這個注解作?在請求正?(body)的數據綁定,請求參數必須在寫在請求正?中。
json格式字符串就在body(請求正文)中。
@RequestMapping("/r10")public String r10(@RequestBody Student student) {return "接收到參數student: " + student;}
獲取URL中參數–@PathVariable
@PathVariable:該注解主要作?在請求URL路徑上的數據綁定,默認傳遞參數寫在URL上,SpringMVC就可以獲取到。
@RequestMapping("/article/{articleId}")public String r11(@PathVariable("articleId") Integer articleId){//@PathVariable從url中獲取參數return "接收到參數articleId: " + articleId;}@RequestMapping("/article/{articleId}/{name}")public String r12(@PathVariable("articleId") Integer articleId,@PathVariable("name") String name){return "接收到參數articleId: " + articleId + " name: " + name;}
傳遞文件–@RequestPart
@RequestPart(“file”) 也是起到類似于賦值的功能
@RequestMapping("/r13")public String r13(@RequestPart("file") MultipartFile file) {//@RequestPart("file") 也是起到類似于賦值的功能String originalFilename = file.getOriginalFilename();return "接收文件,原始名稱: " + originalFilename;}
獲取HTTP請求中的Header信息–@RequestHeader
傳統獲取header
獲取Header也是從 HttpServletRequest 中獲取,使用 HttpServletRequest 提供的getHeader方法來獲取,參數對應HTTP請求報頭的 Key 。
@RequestMapping("/getHeader")public String getHeader(HttpServletRequest request) {String userAgent = request.getHeader("User-Agent");return "從header中獲取信息,useragent: "+userAgent;}
簡潔獲取Header
@RequestHeader 注解的參數值為HTTP請求報頭中的 Key。
@RequestMapping("/getHeader2")public String getHeader2(@RequestHeader("User-Agent") String userAgent) {return "從header中獲取信息,useragent: "+userAgent;}
Cookie與Session
Cookie
Cookie,其實就是儲存在用戶本地終端上的數據(通常經過加密),由用戶計算機暫時或永久保存的信息,類型為“小型文本文件”。
可以理解是某些網站為了辨別用戶身份,進行Session跟蹤而儲存在用戶本地終端上的數據。
Cookie機制
HTTP是無狀態的,不能保存每次提交的信息,如果用戶發來一個新請求,服務器無法知道它是否與上次的請求有聯系。
cookie的出現就是為了解決這個問題
登錄后服務器返回一些數據(cookie)給瀏覽器,然后瀏覽器保存在本地,當該用戶再次發送請求的時候,就會自動的把上次請求存儲的cookie數據自動的攜帶給服務器,服務器通過瀏覽器攜帶的數據就能判斷當前用戶的狀態。
此時在服務器這邊就需要記錄"令牌"信息,以及令牌對應的用戶信息,這個就是 Session 機制所做的工作。
Session
Session–回話、對話:在計算機領域,會話是?個客戶與服務器之間的不中斷的請求響應,當客戶明確結束會話或服務器在?個時限內沒有接受到客?的任何請求時,會話就結束了。
服務器同?時刻收到的請求是很多的,服務器需要清楚的區分每個請求是從屬于哪個客戶,也就是屬于哪個會話,就需要在服務器這邊記錄每個會話以及與客戶的信息的對應關系。
Session是服務器是為了保存用戶信息?創建的?個特殊的對象。
Session的本質就是?個 “哈希表”,存儲了?些鍵值對結構,Key 就是SessionID,Value 就是?戶信息(?戶信息可以根據需求靈活設計)。
SessionId 是由服務器?成的?個 “唯?性字符串”,從 Session 機制的?度來看,這個唯?性字符串稱為 “SessionId”,但是站在整個登錄流程中看待,也可以把這個唯?性字符串稱為 “token”。
Cookie與Session交互
- 當用戶登錄的時候,服務器在 Session 中新增?個新記錄,并把 sessionId 返回給客?端(通過 HTTP 響應中的
Set-Cookie 字段返回) 。 - 客戶端后續再給服務器發送請求的時候,需要在請求中帶上 sessionId(通過 HTTP 請求中的 Cookie 字段帶上)。
- 服務器收到請求之后,根據請求中的 sessionId在 Session 信息中獲取到對應的用戶信息,再進?后續操作,找不到則重新創建 Session ,并把SessionID返回。
- Session 默認是保存在內存中的,如果重啟服務器則 Session 數據就會丟失。
- 同一客戶端啟動二次session_start的話,session_id是不一樣的。
常見面試題
Cookie 和 Session 的區別
Cookie 是客戶端保存用戶信息的?種機制,Session 是服務器端保存用戶信息的?種機制。
Cookie 和Session之間主要是通過 SessionId 關聯起來的,SessionId 是 Cookie 和 Session 之間的橋梁。
Cookie 和 Session 經常會在?起配合使?,但是不是必須配合。
Session 中的 sessionId 也不需要非得通過 Cookie/Set-Cookie 傳遞,比如通過URL傳遞。
Session產生的SessionId放在Cookie里面,如果用戶把Cookie禁止掉,是不是Session也不能用了呢?
禁止掉cookie后,session當然可以用,不過通過其他的方式來獲得這個sessionid,比如,可以跟在url的后面,或者以表單的形勢提交到服務器端,從而使服務器端了解客戶端的狀態。
獲取Cookie與session
獲取Cookie
傳統獲取Cookie
Spring MVC是基于 Servlet API 構建的原始 Web 框架,也是在Servlet的基礎上實現的。HttpServletRequest , HttpServletResponse 是Servlet提供的兩個類,是 Spring MVC 的內置對象,要時直接在?法中添加聲明即可。
HttpServletRequest 對象代表客戶端的請求,當客戶端通過HTTP協議訪問服務器時,HTTP請求頭中的所有信息都封裝在這個對象中,通過這個對象提供的?法,可以獲得客戶端請求的所有信息。
HttpServletResponse 對象代表服務器的響應,HTTP響應的信息都在這個對象中,?如向客戶端發送的數據,響應頭、狀態碼等,通過這個對象提供的?法,可以獲得服務器響應的所有內容。
該方法通過遍歷 request 中所有 Cookie 得到一個 cookies數組。
@RequestMapping("getC")public String getCookie(HttpServletRequest request, HttpServletResponse response) {Cookie[] cookies = request.getCookies();if (cookies != null) {Arrays.stream(cookies).forEach(cookie -> {System.out.println(cookie.getName() + " : " + cookie.getValue());});}return "獲取Cookie";}
此時沒有設置Cookie,通過瀏覽器訪問:http://127.0.0.1:8080/getC ,得到Cookie為null
通過PostMan可以設置?下Cookie的值,進而進行測試。
簡潔獲取Cookie
@CookieValue(“Cookie_1”)只能獲取Cookie數組中某個指定cookie,這里指定的是剛才通過PostMan創建的Cookie。
@RequestMapping("/getC2")public String getCookie2(@CookieValue("Cookie_1") String cookie) {return "從Cookie中獲取值,cookie"+cookie;}
獲取Session
設置Session
Session是服務器端的機制,需要先存儲,才能再獲取。
該方法創建了一個Session----SessionId : {name:zhangsan}。
@RequestMapping("/setSess")public String setSession(HttpServletRequest request) {//從Cookie中獲取到了sessionID,根據senssionID獲取session對象,如果沒有獲取到,會創建一個session對象HttpSession session = request.getSession();session.setAttribute("name","zhangsan");return "設置session成功";}
傳統獲取Session
Object getAttribute(String name):返回在該 session 會話中具有指定名稱的對象,如果沒有指定名稱的對象,則返回null。
該方法返回服務器端name的信息。
@RequestMapping("/getSess")public String getSession(HttpServletRequest request) {//從Cookie中獲取到了sessionID,根據senssionID獲取session對象HttpSession session = request.getSession();String name = (String)session.getAttribute("name");return "從session中獲取name: "+name;}
簡潔獲取Session
@RequestMapping("getSess2")public String getSession(HttpSession session) {String name = (String) session.getAttribute("name");return "name:" + name;}
上述方法雖然很簡潔,但是Spring封裝了更為簡潔的方法。
通過@SessionAttribute(“name”)這個注解來獲取session對象的name。
@RequestMapping("/getSess3")public String getSession3(@SessionAttribute("name") String name) {return "從session中獲取name: "+name;}