一:了解Spring Web MVC
(1)關(guān)于Java開發(fā)
??Java開發(fā)大多數(shù)場景是業(yè)務(wù)開發(fā)
比如說京東的業(yè)務(wù)就是電商賣貨、今日頭條的業(yè)務(wù)就推送新聞;快手的業(yè)務(wù)就是短視頻推薦
(2)Spring Web MVC的簡單理解
??Spring Web MVC:如何使用Spring去建網(wǎng)站
(我們知道既然Java是做業(yè)務(wù)開發(fā)就避免不了建網(wǎng)站)
?? Spring Web MVC是?個Web框架;也可以簡稱為Spring MVC?
①Spring:Spring就是一個框架,能讓我們更快速、便捷和高效的去完成Java開發(fā)
②Web:表示做的是網(wǎng)頁、網(wǎng)站的開發(fā)
③MVC:MVC是Model View Controller的縮寫,它是軟件工程中的一種軟件架構(gòu)設(shè)計模式
(MVC就是把項目分為模型、視圖和控制器三個基本部分 )
二:學(xué)習(xí)Spring Web MVC前提
(1)了解客戶端和服務(wù)器的交互
??通過客戶端和服務(wù)器進(jìn)行交互主要分為三個方面
(客戶端:瀏覽器/用戶程序)
①建立連接:將客戶端(瀏覽器/用戶程序)和服務(wù)器(Java程序)連接起來,也就是訪問?個瀏覽器地址能夠調(diào)用到我們Java寫的的Spring程序
②請求:當(dāng)建立完連接之后,客戶端會向服務(wù)器發(fā)出一個請求,此時在服務(wù)器端就得獲取到請求的參數(shù);因此,總的來說請求這塊的主要是服務(wù)器為了獲取請求的參數(shù)
③響應(yīng):服務(wù)器獲取請求參數(shù)后,然后執(zhí)行業(yè)務(wù)邏輯,執(zhí)行完畢就把執(zhí)行的結(jié)果返回給客戶端
??對于Spring Web MVC來說,掌握了以上3個功能就相當(dāng)于掌握了Spring Web MVC
(2)項目準(zhǔn)備
??Spring MVC項目創(chuàng)建和SpringBoot創(chuàng)建項目相同,在創(chuàng)建的時候選擇Spring Web就相當(dāng)于創(chuàng)建了Spring MVC的項目
三:Spring Web MVC-建立連接
(1)@RequestMapping概念
①作用:實現(xiàn)URL路由映射,也就是實現(xiàn)客戶端連接服務(wù)器的作用
(即瀏覽器連接Java后端它們通過@RequestMapping建立連接)
②訪問:IP:端口號/類的路徑+方法路徑
(類的路徑和方法路徑其實就是@RequestMapping里的參數(shù);區(qū)分方式主要看它寫在類外還是類內(nèi))
③理解:表示服務(wù)器收到請求時,路徑為XXX的請求就會調(diào)用XXX路徑對應(yīng)這個方法的代碼
(2)@RequestMapping使用方式
1.使用方式和細(xì)節(jié)
??@RequestMapping既可以修飾類,也可以修飾方法
??@RequestMapping參數(shù)里的“/”可以省略,但還是建議加上
2.方法路徑
??方法路徑:寫在類內(nèi);此時如果沒有類的路徑直接通過方法路徑即可訪問網(wǎng)址
??下列代碼表示服務(wù)器收到請求時,路徑為/sayhi的請求就會調(diào)用sayHi這個方法里的代碼
package com.example.demo.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; //此時沒有類的路徑,那么類的路徑就為空,直接訪問方法路徑即可 @RestController public class HelloController { @RequestMapping("/sayhi") //方法路徑 //sayHi()方法就是需要在網(wǎng)站上顯示什么;方法名不要求與路徑名相同 //例如我的路徑名是sayhi,方法名是sayHi public String sayHi() { return "hi,SpringBoot"; } }
3.類的路徑
??類的路徑:寫在類外;此時需要通過類的路徑+方法路徑才能訪問網(wǎng)址
package com.example.demo.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/hlizoo") //類路徑 @RestController public class HelloController { @RequestMapping("/sayhi") //方法路徑 public String sayHi() { return "hi,SpringBoot"; } }
4.路徑嵌套
??路徑也可以包含多層,即多層套娃
package com.example.demo.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/hlizoo/cool") //類路徑;多層路徑 @RestController public class HelloController { @RequestMapping("/sayhi/no") //方法路徑;多層路徑 public String sayHi() { return "hi,SpringBoot"; } }
(3)@RequestMapping限制請求
???@RequestMapping支持所有的請求,比如GET、POST、PUT等等
??@RequestMapping如果沒有寫屬性,默認(rèn)只有路徑,此時可以寫Method屬性來限制請求的方法
(比如以下代碼:說明路徑是/hlizoo/sayhi和請求方法是GET時才調(diào)用sayHi方法)
package com.example.demo.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/hlizoo") //類路徑 @RestController public class HelloController { //當(dāng)你寫了mehod,前面的路徑就會默認(rèn)加上value @RequestMapping(value = "/sayhi",method = RequestMethod.GET) //方法路徑;此時指定是GET請求 public String sayHi() { return "hi,SpringBoot"; } }
四:Spring Web MVC-請求
(1)明確請求部分的學(xué)習(xí)內(nèi)容
??學(xué)習(xí)Spring的請求,主要是學(xué)習(xí)如何傳遞參數(shù)到后端(服務(wù)器)以及后端(服務(wù)器)如何接收
??原因就是當(dāng)我們訪問不同的路徑,就會發(fā)送不同的請求,在發(fā)送請求時,可能會帶?些參數(shù),我們就要學(xué)習(xí)如何傳參和接參
(2)傳遞單個參數(shù)的接收方法
1.方法
??方法:接收單個參數(shù),直接在Spring MVC的方法形參中聲明參數(shù)數(shù)據(jù)類型和參數(shù)名即可
??參數(shù)類型建議使用包裝數(shù)據(jù)類型
(1)如果傳的是基本數(shù)據(jù)類型,必須要傳參傳值,否則會報錯
(2)如果傳的是包裝數(shù)據(jù)類型,不傳參傳值不會報錯,而是返回null
2.后端代碼
package com.example.demo.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/m1") //此時就代表了接收了一個name參數(shù) //至于這個name前端是如何給的,作為后端人員并不關(guān)心,我的要求只是一個name參數(shù)而已 //接收單個參數(shù),直接在m1方法寫參數(shù)數(shù)據(jù)類型和參數(shù)名即可 public String m1(String name){ return "接收到的參數(shù)name:"+name; } }
3.?利用Postman發(fā)送單個參數(shù)的請求
①當(dāng)沒有傳遞name參數(shù)的情況
②當(dāng)傳遞了name參數(shù)的情況
4.注意事項
(3)傳遞多個參數(shù)的接收方法
1.方法
??方法:接收多個參數(shù),直接在Spring MVC的方法形參中聲明多個參數(shù)數(shù)據(jù)類型和參數(shù)名即可
??參數(shù)類型建議使用包裝數(shù)據(jù)類型
(1)如果傳的是基本數(shù)據(jù)類型,必須要傳參傳值,否則會報錯
(2)如果傳的是包裝數(shù)據(jù)類型,不傳參傳值不會報錯,而是返回null
2.后端代碼
package com.example.demo.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/param") @RestController public class ParamController { //接收多個參數(shù),直接在m2方法寫多個參數(shù)數(shù)據(jù)類型和參數(shù)名即可 @RequestMapping("/m2") public String m2(String name,Integer age){ return "接收到的參數(shù)name:"+name+",age:"+age; } }
3.?利用Postman發(fā)送多個參數(shù)的請求
4.注意事項
?
(4)傳遞對象的接收方法
1.方法
??方法
①先寫一個類,把這些參數(shù)封裝為一個對象,寫上Getter和Setter以及toString方法
②在方法的形參部分寫上類和對象名
(原因:當(dāng)參數(shù)過多時,方法聲明就要寫很多的形參,形參太多既不雅觀修改也不方便,不妨寫個類封裝成對象)
2.后端代碼
①新建一個Person類
package com.example.demo; public class Person { Integer id; String name; Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
②方法的代碼
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/m4") public String m4(Person person){ return "接收到的參數(shù)person:"+person.toString(); } }
?3.利用Postman發(fā)送請求
(5)后端參數(shù)重命名
1.方法
??方法:@RequestParam來重命名前后端的參數(shù)值
①進(jìn)行了重命名后,就一定要使用@RequestParam里寫的名字來進(jìn)行傳參
②進(jìn)行了重命名后,如果使用了其他名字來進(jìn)行傳參,要么報錯要么為null
2.后端代碼
??情況:某些特殊的情況下,前端傳遞的參數(shù)key和我們后端接收的key可以不一致
比如后端是使用username字段來接收的,而前端卻用了name字段來傳遞,這樣就會出現(xiàn)參數(shù)接收不到的情況
package com.example.demo.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/m5") public String m5(@RequestParam("name") String username){ return "接收到的參數(shù)name:"+username; } }
3.?利用Postman發(fā)送請求
①當(dāng)用name作為字段來傳參時,可以順利的接收到請求
②當(dāng)用username作為字段傳參的時候,反而報錯了
4.注意事項
??①如果使用了@RequestParam且不加任何屬性,那么它里面的參數(shù)就是必傳參數(shù)了,如果使用了其它的字段來傳參就會報錯
??(2)@RequestParam里如果添加了required屬性,required為false則里面的參數(shù)就不是必傳參數(shù)了,使用了其他字段傳參不會報錯只會變成null
(6)傳遞數(shù)組的接收方法
1.方法
??方法:在方法形參中寫個數(shù)組即可;因為Spring MVC可以自動綁定數(shù)組參數(shù)的賦值
??當(dāng)我們的請求中,同一個參數(shù)名的參數(shù)有多個時,瀏覽器會給我們封裝成一個數(shù)組
2.后端代碼
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Arrays; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/m6") public String m6(String []arrayParam){ return "接收到的參數(shù)arrayParam:"+ Arrays.toString(arrayParam); } }
3.利用瀏覽器發(fā)送請求
??方式一:用瀏覽器發(fā)送多個相同參數(shù)名的參數(shù),參數(shù)之間用&分割
(當(dāng)請求中同一個參數(shù)名arrayParam的參數(shù)有多個時,瀏覽器會給我們封裝成一個數(shù)組)
??方式二:用瀏覽器發(fā)送多個相同參數(shù)名的參數(shù),參數(shù)之間用,分割
(當(dāng)請求中同一個參數(shù)名arrayParam的參數(shù)有多個時,瀏覽器會給我們封裝成一個數(shù)組)
(7)傳遞集合的接收方法
1.方法
??方法:先使用@RequestParam綁定參數(shù)關(guān)系,然后寫集合類和對象名即可
??集合接收的方法和數(shù)組類似,只不過在默認(rèn)情況下,請求中參數(shù)名相同的多個值,是封裝到數(shù)組;如果要封裝到集合,要使用@RequestParam綁定參數(shù)關(guān)系
2.后端代碼
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/m7") public String m7(@RequestParam List<String> listParam){ return "接收到的參數(shù)listParam:"+ listParam + "長度為:"+listParam.size(); } }
3.利用Postman發(fā)送請求
?(8)傳遞JSON數(shù)據(jù)的接收方法
1.JSON定義
JSON:JavaScriptObjectNotation 【JavaScript對象表示法】
??①JSON就是?種數(shù)據(jù)格式,有自己的格式和語法,使用文本表示一個對象或數(shù)組的信息
??②JSON本質(zhì)是字符串;主要負(fù)責(zé)在不同的語言中數(shù)據(jù)傳遞和交換
2.JSON語法
3.JSON字符串和Java對象互轉(zhuǎn)
??使用ObjectMapper對象提供的兩個方法,可以完成對象和JSON字符串的互轉(zhuǎn)
①writeValueAsString: 把Java對象轉(zhuǎn)為JSON字符串
(參數(shù)寫的是Java對象)
②readValue: 把JSON字符串轉(zhuǎn)為Java對象
(第一個參數(shù)是JSON字符串;第二個參數(shù)是Java對象)
public class JSONUtils { private static ObjectMapper objectMapper = new ObjectMapper(); public static void main(String[] args) throws JsonProcessingException { Person person = new Person(); person.setId(5); person.setName("zhangsan"); person.setPassword("123456"); //Person對象轉(zhuǎn)為JSON字符串 String jsonStr = objectMapper.writeValueAsString(person); System.out.println("JSON字符串為:"+jsonStr); //JSON字符串轉(zhuǎn)為對象 Person p = objectMapper.readValue(jsonStr,Person.class); System.out.println("轉(zhuǎn)換的對象 id:"+p.getId()+",name:"+p.getName()+",password:"+p.getPassword()); } }
4.方法
??方法:接收J(rèn)SON對象,需要使用@RequestBody注解
??RequestBody:請求正文,意思是這個注解作用在請求正文的數(shù)據(jù)綁定,請求參數(shù)必須寫在請求正文中
5.后端代碼
①創(chuàng)建一個Person對象
package com.example.demo; public class Person { Integer id; String name; Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
②方法的代碼
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/m8") public String m8(@RequestBody Person person){ return "接收到的數(shù)據(jù)person:"+person.toString(); } }
6.利用Postman發(fā)送JSON請求
(9)獲取URL中的參數(shù)
1.方法
??方法:使用到@PathVariable來拿到URL的參數(shù)
??@PathVariable主要作用在請求URL路徑上的數(shù)據(jù)綁定,默認(rèn)傳遞參數(shù)寫在URL上,SpringMVC就可以獲取到
2.后端代碼
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.web.bind.annotation.*; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { //注意@RequestMapping的參數(shù) @RequestMapping("/m9/{userId}") public String m9(@PathVariable Integer userId) { return "userId:"+userId; } }
3.利用Postman發(fā)送請求
4.注意事項
(10)上傳文件
1.方法
??方法:使用到@RequestPart
①文件我們一般用MultipartFile file來接收,因此方法的形參一般寫@RequestPart?MultipartFile file
②transferTo方法可以將文件上傳且保存到指定路徑
2.后端代碼
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/m10") public String m10(@RequestPart MultipartFile file) throws IOException { //獲取文件名稱 String filename = file.getOriginalFilename(); //上傳文件到指定路徑 file.transferTo(new File("D:/test/"+file.getOriginalFilename())); return "success,"+"文件名稱:"+filename; } }
3.利用Postman發(fā)送圖片請求
4.注意事項
(11)獲取Cookie/Session
1.為什么會出現(xiàn)Cookie與Session
??原因:HTTP協(xié)議自身是屬于"無狀態(tài)"協(xié)議,即HTTP協(xié)議無記憶功能
??"無狀態(tài)"的含義指的是:默認(rèn)情況下HTTP協(xié)議的客戶端和服務(wù)器之間的這次通信,和下次通信之間沒有直接的聯(lián)系;但是實際開發(fā)中,我們很多時候是需要知道請求之間的關(guān)聯(lián)關(guān)系的, 例如登錄網(wǎng)站成功后,第?次訪問的時候服務(wù)器就能知道該請求是否是已經(jīng)登陸過了
2.區(qū)分Cookie與Session概念
?①Cookie是瀏覽器存儲(臨時)數(shù)據(jù)的機(jī)制
②Session是服務(wù)器存儲(臨時)數(shù)據(jù)的機(jī)制
(作用:存儲用戶的詳細(xì)信息;并給用戶分配一個唯一值sessionid;后續(xù)再訪問網(wǎng)站的其他頁面時,HTTP請求就會自動帶上sessionid,通過sessionid就能找到對應(yīng)的Session即對應(yīng)的用戶)
③兩者的區(qū)別
④兩者的聯(lián)系
3.詳解Cookie
①Cookie是瀏覽器本地存儲數(shù)據(jù)的一種機(jī)制
??(此時在服務(wù)器這邊就需要記錄"令牌"信息,以及令牌對應(yīng)的用戶信息,這個就是Session機(jī)制所做的工作;下文詳細(xì)說)
②作用:實現(xiàn) "身份標(biāo)識" 的功能;每個不同的域名下都可以有不同的Cookie, 不同網(wǎng)站之間的Cookie并不沖突
??(Cookie會存儲很多鍵值對,往往會有一個很重要的鍵值對是用來表示用戶的“身份信息”,即標(biāo)識當(dāng)前請求是來自于哪個用戶的;就會產(chǎn)生這么一種場景,比如你登陸一個網(wǎng)站,后續(xù)再訪問這個網(wǎng)站頁面,就無需登錄了,而且就算關(guān)了電腦,第二天重開網(wǎng)頁,依然不需要登錄)
③Cookie的原理:Cookie是按鍵值對的形式來存儲了一些字符串,這些鍵值對往往都是由服務(wù)器返回回來的,瀏覽器把這些鍵值對按照“域名”維度進(jìn)行分類存儲,意思就是說不同網(wǎng)站就有不同的Cookie,例如百度有百度的Cookie,搜狗有搜狗的Cookie,這些Cookie的內(nèi)容都是由程序猿自己定義的
④Cookie的保存機(jī)制:
⑤總結(jié):
(1)Cookie從哪來?
答:Cookie是從服務(wù)器返回給瀏覽器的
(2)Cookie是如何保存的?保存在哪?
答:瀏覽器按照不同的域名分別存儲Cookie,域名與域名之間的Cookie是不能互相干擾的,即每一組域名都有自己的Cookie;Cookie保存在瀏覽器所在電腦的硬盤上,就算關(guān)機(jī)也不會影響到
(3)Cookie中的內(nèi)容是啥?
答:Cookie中的內(nèi)容是鍵值對結(jié)構(gòu)的數(shù)據(jù),這里的鍵值對是由程序猿自己定義的
(4)Cookie中的內(nèi)容到哪里去?
答:后續(xù)訪問該網(wǎng)站的各個頁面時,就都會在請求中帶上Cookie,服務(wù)器就可以進(jìn)一步知道客戶端用戶的詳細(xì)情況?
⑥Cookie的缺點:
??Cookie是可以偽造的
??問:瀏覽器要保存數(shù)據(jù)為啥要先保存到Cookie再讓Cookie保存到硬盤,而不能直接往硬盤寫入一個文件保存?
答:往硬盤寫入是絕對不行的!因為如果你讓網(wǎng)頁能夠輕易的訪問你的文件系統(tǒng),這是一件非常危險的事情;想一下如果你上一種病毒網(wǎng)站,網(wǎng)站直接給你的電腦上下個病毒或者直接把你硬盤上已有的數(shù)據(jù)刪除掉了,那不就完蛋了?
??因此為了保證安全,瀏覽器會對網(wǎng)頁的功能作出限制,禁止訪問硬盤就是對網(wǎng)頁的其中一個限制;所以為了既能保證安全也能保存數(shù)據(jù),瀏覽器就提供了一個Cookie功能!
4.了解Session
???①Sessionid保存在Cookie中,后面再去訪問服務(wù)器的時候,我的Cookie就帶著Sessionid去訪問,然后服務(wù)器就可以根據(jù)這個Sessionid去返回對應(yīng)的Session了
(但在服務(wù)器這邊也需要記錄SessionId,以及SessionId對應(yīng)的用戶信息Session)
??②Session的缺點:存在分布式問題
5.獲取Cookie的普通方法
??普通方法:需要用到HttpServletRequest,HttpServletResponse,它們是Servlet提供的兩個類
??①HttpServletRequest對象代表客戶端的請求,當(dāng)客戶端通過HTTP協(xié)議訪問服務(wù)器時,HTTP請求頭中的所有信息都封裝在這個對象中,通過這個對象提供的方法,可以獲得客戶端請求的所有信息
??②HttpServletResponse對象代表服務(wù)器的響應(yīng),HTTP響應(yīng)的信息都在這個對象中,比如向客戶端發(fā)送的數(shù)據(jù)、響應(yīng)頭、狀態(tài)碼等;通過這個對象提供的方法,可以獲得服務(wù)器響應(yīng)的所有內(nèi)容
??這兩個類是Spring內(nèi)置的對象,當(dāng)你需要的時候,直接在方法聲明加上即可
6.獲取Cookie的后端代碼(普通版)
package com.example.demo.Controller; import com.example.demo.Person; import com.sun.deploy.net.HttpResponse; import org.springframework.http.HttpRequest; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/getcookie") public String m11(HttpServletRequest request, HttpServletResponse response){ //拿到cookie的對象 Cookie[] cookies = request.getCookies(); //打印cookie的值 if(cookies!=null){ for (Cookie cookie : cookies) { System.out.println(cookie.getName()+":"+cookie.getValue()); } } return "獲取cookie成功!"; } }
7.獲取Cookie的簡單方法
??簡單方法:使用@CookieValue即可
??使用簡單的方法一個@CookieValue一次只能拿一個Cookie,要想拿多個Cookie,就得使用多個@CookieValue
??(它不像普通方法那樣一次性可以拿完全部的Cookie然后保存到數(shù)組中)
8.獲取Cookie的后端代碼(簡單版)
package com.example.demo.Controller; import com.example.demo.Person; import com.sun.deploy.net.HttpResponse; import org.springframework.http.HttpRequest; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/getcookie2") public String m12(@CookieValue String bite,@CookieValue String aaa){ return "cookie存儲的值bite:"+bite+",aaa:"+aaa; } }
9.利用瀏覽器設(shè)置Cookie(普通版)
①右鍵瀏覽器,選擇檢查,選擇Applicaition
②選擇左側(cè)欄Storage欄中的Cookies
③自主添加Name和Value,比如我添加如下圖所示的
④此時再次刷新網(wǎng)頁并觀看IDEA控制臺
10.利用瀏覽器設(shè)置Cookie(簡單版)
??當(dāng)設(shè)置好Cookie后,直接就可以獲取了
11.獲取Session的普通方法
??普通方法①:基于HttpServletRequest來存儲和獲取的
??普通方法②:基于HttpSession來存儲和獲取的
HttpServletRequest、HttpServletResponse、HttpSession都是Spring內(nèi)置對象(內(nèi)置對象:需要使用的時候直接方法聲明即可)
??Session是服務(wù)器端的機(jī)制,我們需要先存儲,才能再獲取
12.獲取Session的后端代碼(普通版)
package com.example.demo.Controller; import com.example.demo.Person; import com.sun.deploy.net.HttpResponse; import org.springframework.http.HttpRequest; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { //session要先存儲才能獲取;并且session不像cookie那樣可以設(shè)置 //這里先存儲session @RequestMapping("/setSession") public String setSession(HttpServletRequest request){ HttpSession session = request.getSession(); session.setAttribute("username","zhangsan"); return "success"; } //第一種普通方法:使用Spring內(nèi)置對象HttpServletRequest @RequestMapping("/getsession") public String m13(HttpServletRequest request){ //參數(shù)為true,沒有session則創(chuàng)建session //參數(shù)為false,沒有session則放回null HttpSession session = request.getSession(false); if (session!=null){ String username = (String) session.getAttribute("username"); return "登錄用戶:"+username; } return "session為空"; } //第二種普通方法:使用Spring內(nèi)置對象HttpSession @RequestMapping("/getsession3") public String m15(HttpSession session){ String username = (String) session.getAttribute("username"); return "登錄用戶:"+username; } }
13.觀察瀏覽器(普通版)
①先輸入setSession來觀察瀏覽器效果
(因為session要先存儲才能獲取)
②再去觀察Cookie的效果,可以看到多了一個JSESSIONID
14.獲取Session的簡單方法
??方法:使用@SessionAttribute即可
??使用簡單的方法一個@SessionAttribute一次只能拿一個Session,要想拿多個Session,就得使用多個@SessionAttribute
??使用@SessionAttribute的參數(shù)默認(rèn)是必傳參數(shù),如果讓required=false,就不是必傳參數(shù)了
15.獲取Session的后端代碼(簡單版)
package com.example.demo.Controller; import com.example.demo.Person; import com.sun.deploy.net.HttpResponse; import org.springframework.http.HttpRequest; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { //session要先存儲才能獲?。徊⑶襰ession不像cookie那樣可以設(shè)置 //這里先存儲session @RequestMapping("/setSession") public String setSession(HttpServletRequest request){ HttpSession session = request.getSession(); session.setAttribute("username","zhangsan"); return "success"; } @RequestMapping("/getsession2") public String m14(@SessionAttribute(required = false) String username){ return "username:"+username; } }
16.觀察瀏覽器(簡單版)
①依舊是輸入先輸入setSession來觀察瀏覽器效果
(因為session要先存儲才能獲取)
②此時去觀察簡單方法的瀏覽器效果
(12)獲取Header
1.獲取Header的普通方法
??普通方法:依舊使用內(nèi)置對象HttpServletRequest,通過HttpServletRequest提供的getHeader方法來獲取,參數(shù)對應(yīng)HTTP請求報頭的"Key"
2.后端代碼(普通版)
package com.example.demo.Controller; import com.example.demo.Person; import com.sun.deploy.net.HttpResponse; import org.springframework.http.HttpRequest; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/getHeader") public String m16(HttpServletRequest request){ String UserAgent = request.getHeader("User-Agent"); return "User-Agent:"+UserAgent; } }
3.觀察瀏覽器效果(普通版)
4.獲取Header的簡單方法
??簡單方法:使用@RequestHeader;@RequestHeader的參數(shù)值為HTTP請求報頭中的"Key",如果你想賦值給哪個變量,在后面寫上即可
5.后端代碼(簡單版)
package com.example.demo.Controller; import com.example.demo.Person; import com.sun.deploy.net.HttpResponse; import org.springframework.http.HttpRequest; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; @RequestMapping("/param") @RestController public class ParamController { @RequestMapping("/getHeader2") public String m17(@RequestHeader("User-Agent") String UserAgent){ return "User-Agent:"+UserAgent; } }
6.觀察瀏覽器效果(簡單版)
五:Spring Web MVC-響應(yīng)
(1)返回靜態(tài)頁面
1.方法
??方法:使用的是@Controller
(不是@RestController,跟上述的請求不一樣,下文詳細(xì)分析)
??返回static目錄下的靜態(tài)頁面,直接在return后面加上“/XXX.html”即可
(比如:return "/login.html")
2.前端代碼
①先在static目錄下創(chuàng)建一個名字為index的html文件
②因為是用來測試的,我們前端代碼寫得簡單一點就行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index首頁</title> </head> <body> <h1>我是index頁面</h1> </body> </html>
③重新啟動服務(wù)器,訪問index.html看看效果如何
(static目錄下的靜態(tài)頁面可直接訪問)
3.后端代碼
package com.example.demo.Controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @RequestMapping("/return") @Controller //←注意這里用的是Controller public class ReturnController { @RequestMapping("/index") public String returnIndex(){ return "/index.html"; } }
4.觀察瀏覽器效果
5.初次了解@RestController
??①@RestController = @Controller + @ResponseBody
(1)@Controller : 定義?個控制器,Spring框架啟動時加載,把這個對象交給Spring管理
(2)@ResponseBody : 定義返回的數(shù)據(jù)格式為非視圖,返回?個text/html數(shù)據(jù)信息
??②@Controller返回視圖頁面;@ResponseBody返回頁面的數(shù)據(jù)
??③如果想返回視圖的話,只需要把@ResponseBody去掉就可以了,也就是@Controller
6.初次了解@Controller
??作用:Spring框架啟動時加載,把這個對象交給Spring管理;然后去找需要返回的視圖,如果找到就返回例如HTML頁面等等的視圖,沒找到就報錯404
(即是說把整個代碼交給Spring,告訴Spring幫我們?nèi)ス芾恚缓罄m(xù)我們訪問時,才能訪問到)
(2)返回數(shù)據(jù)
1.方法
??方法:使用的是@ResponseBody;表示返回數(shù)據(jù)
(比如return "/index.html",@Controller會去查找index.html文件,但是如果加了@ResponseBody,就直接把"/index.html"當(dāng)做?個文本數(shù)據(jù)返回給前端)
①@ResponseBody既是類注解,又是方法注解
②@ResponseBody如果作用在類上,表示該類的所有方法返回的都是數(shù)據(jù)
(1)在類上添加@ResponseBody就相當(dāng)于在所有的方法上添加了@ResponseBody
(2)相同,如果類上有@RestController時,表示所有的方法上添加了@ResponseBody,也就是當(dāng)前類下所有的方法返回值都為響應(yīng)數(shù)據(jù)?
③@ResponseBody如果作用在方法上,表示該方法返回的是數(shù)據(jù)
2.后端代碼
package com.example.demo.Controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @RequestMapping("/return") @Controller //←注意這里用的是Controller,下面如果要返回數(shù)據(jù)必須要加上@ResponseBody public class ReturnController { @ResponseBody //作用于方法上,表示returnData方法返回的是一個文本數(shù)據(jù) @RequestMapping("/returndata") public String returnData(){ return "/index.html"; //此時加了@ResponseBody,就直接返回一個文本數(shù)據(jù) } }
3.觀察瀏覽器效果
(3)返回HTML代碼片段
1.方法
??方法:使用@ResponseBody也可返回HTML的文本數(shù)據(jù)
??原因:后端返回數(shù)據(jù)時,如果數(shù)據(jù)中有HTML代碼,也會被瀏覽器解析
2.后端代碼
package com.example.demo.Controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @RequestMapping("/return") @Controller //←注意這里用的是Controller,下面如果要返回數(shù)據(jù)必須要加上@ResponseBody public class ReturnController { @ResponseBody @RequestMapping("/returnHTML") public String returnHTML(){ return "<h1>這是一個HTML片段</h1>"; } }
3.觀察瀏覽器效果
(4)返回JSON
1.方法
??方法:使用@ResponseBody;要想返回JSON則返回類型是對象或者M(jìn)ap即可
2.后端代碼(示例一)
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @RequestMapping("/return") @Controller //←注意這里用的是Controller,下面如果要返回數(shù)據(jù)必須要加上@ResponseBody public class ReturnController { @ResponseBody @RequestMapping("/returnJSON") public Person returnjson(){ //使用之前的Person類 Person person = new Person(); person.setId(7); person.setName("hlizoo"); person.setAge(20); return person; } }
3.觀察瀏覽器效果(示例一)
4.后端代碼(示例二)
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashMap; import java.util.Map; @RequestMapping("/return") @Controller //←注意這里用的是Controller,下面如果要返回數(shù)據(jù)必須要加上@ResponseBody public class ReturnController { @ResponseBody @RequestMapping("/returnMAP") public Map<String,String> returnmap(){ Map<String,String> kv = new HashMap<>(); kv.put("k1","v1"); kv.put("k2","v2"); kv.put("k3","v3"); return kv; } }
5.觀察瀏覽器效果(示例二)
6.注意事項
①當(dāng)我們的返回類型是基本數(shù)據(jù)類型和包裝類型時,Content-Type默認(rèn)是text/html
(比如String、Integer等等)
②當(dāng)我們的返回類型是對象和Map等等時,Content-Type自動設(shè)置為application/json
(只要返回類型是對象和Map時,要想返回json那啥都不用做,瀏覽器自動就搞好了)
(5)設(shè)置狀態(tài)碼
1.方法
??方法:使用Spring MVC內(nèi)置對象HttpServletResponse提供的setStatus方法進(jìn)行設(shè)置
??Spring MVC會根據(jù)我們方法的返回結(jié)果自動設(shè)置響應(yīng)狀態(tài)碼,當(dāng)然我們也可以手動指定狀態(tài)碼
??注意這里的狀態(tài)碼并不影響頁面的展示,就算你的狀態(tài)碼是401,也會顯示你設(shè)置的內(nèi)容
2.后端代碼
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; @RequestMapping("/return") @Controller //←注意這里用的是Controller,下面如果要返回數(shù)據(jù)必須要加上@ResponseBody public class ReturnController { @ResponseBody @RequestMapping("/setStatus") public String setstatus(HttpServletResponse response){ response.setStatus(401); return "設(shè)置狀態(tài)碼"; } }
3.觀察瀏覽器效果
(6)設(shè)置Content-Type
1.方法
??方法:通過設(shè)置@RequestMapping里produces屬性的值,來設(shè)置響應(yīng)的報頭Content-Type
2.后端代碼
package com.example.demo.Controller; import com.example.demo.Person; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; @RequestMapping("/return") @Controller //←注意這里用的是Controller,下面如果要返回數(shù)據(jù)必須要加上@ResponseBody public class ReturnController { @ResponseBody @RequestMapping(value = "/r1",produces = "application/json;charset=utf8") public String r1() { return "{'ok':200}"; } }
3.觀察瀏覽器效果
文章來源:http://www.zghlxwxcb.cn/news/detail-716010.html
(7)自行設(shè)置Header
??方法:通過內(nèi)置對象HttpServletResponse里setHeader方法來設(shè)置響應(yīng)的報頭文章來源地址http://www.zghlxwxcb.cn/news/detail-716010.html
到了這里,關(guān)于Spring Web MVC入門的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!