一、Spring Boot Web MVC 概念
Spring Web MVC 是?個(gè) Web 框架,一開始就包含在Spring 框架里。
1. MVC 定義
軟件?程中的?種軟件架構(gòu)設(shè)計(jì)模式,它把軟件系統(tǒng)分為模型、視圖和控制器三個(gè)基本部分
2. 什么是Spring MVC
MVC 是?種架構(gòu)設(shè)計(jì)模式, 也?種思想, ? Spring MVC 是對 MVC 思想的具體實(shí)現(xiàn)
Spring MVC 是?個(gè)實(shí)現(xiàn)了 MVC 模式的 Web 框架
Spring Boot 只是實(shí)現(xiàn)Spring MVC的其中?種方式而已
Spring Boot 實(shí)現(xiàn)了MVC思想后,就被稱為Spring MVC,可以實(shí)現(xiàn) web功能
Spring Boot 可以添加很多依賴, 借助這些依賴實(shí)現(xiàn)不同的功能. Spring Boot 通過添加Spring Web MVC框架, 來實(shí)現(xiàn)web功能
Spring Boot 結(jié)合自身特點(diǎn)的情況,如下圖,不過核心依舊沒變
3. Spring Boot 不同的傳參介紹
- 普通傳參, 也就是通過查詢字符串來傳參
- form-data
- x-www-form-urlencoded
- raw
- 可以上傳任意格式的?本,可以上傳text、json、xml、html等
4. Spring Boot 不同的傳參方式
如果使用的是基本類型,必須要傳值,不然會(huì)報(bào)錯(cuò),因?yàn)榛绢愋蜔o法被賦值null
(1)傳遞單個(gè)參數(shù)
限制方法
@RequestMapping(value = "demo1",method = RequestMethod.PUT)
public String demo1(String name){
return "接收到的name:" + name;
}
不限制方法
@RequestMapping("demo1")
public String demo1(String name){
return "接收到的name:" + name;
}
(2)傳遞多個(gè)參數(shù)
多個(gè)參數(shù)發(fā)送的時(shí)候,順序是無所謂的
@RequestMapping("demo2")
public String demo2(String name, Integer age){
return "接受到的name:" + name + ",age:" + age;
}
(3)傳遞對象
@RequestMapping("demo3")
public String demo3(Person person){
return person.toString();
}
@RequestMapping("demo4")
public String demo4(@RequestParam("name") String username){
return "接收到的name:" + username;
}
如果進(jìn)行了重命名,就必須要使用@RequestParam注解里的名字
想要把name變成非必傳參數(shù)
計(jì)算機(jī)這邊正規(guī)的還是name,但是程序員這邊是用username代替了name
(4)傳遞數(shù)組/集合
@RequestMapping("demo5")
public String demo5(String[] str){
return "接收到的數(shù)組:" + str.toString() + ",長度是:" + str.length;
}
如果傳的是一個(gè)列表,idea會(huì)把列表默認(rèn)為數(shù)組,需要一個(gè)@RequestParam注解,才能讓idea知道這個(gè)是列表
@RequestMapping("/demo6")
public String m7(@RequestParam(required = false,defaultValue = "zhangsan,lisi,wangwu,zhaoliu") List<String> listParam){
return "接收到的參數(shù)listParam:"+ listParam + ",長度:"+listParam.size();
}
(5)傳遞JSON數(shù)據(jù)
Json 只能接收正文的,而且只能接收J(rèn)SON字符串格式
工作中,上面四種傳參方式都不常用,比起傳單個(gè)/多個(gè)數(shù)據(jù),還是更傾向于傳對象,但是上述方法太過繁瑣,我們一般使用JSON傳遞數(shù)據(jù)
概念:本質(zhì)上是一個(gè)字符串,有著自己的格式和語法,可以描述數(shù)據(jù)信息
語法:
(1)數(shù)據(jù)在 鍵值對(Key/Value) 中
(2)數(shù)據(jù)由逗號 , 分隔
(3)對象用 {} 表示
(4)數(shù)組用 [] 表示
(5)值可以為對象, 也可以為數(shù)組, 數(shù)組中可以包含多個(gè)對象
JSON的兩種結(jié)構(gòu)
- 對象: 大括號 {} 保存的對象是?個(gè)無序的 鍵值對 集合. ?個(gè)對象以左括號 { 開始, 右括號 }
結(jié)束。每個(gè)"鍵"后跟?個(gè)冒號 :,鍵值對使用逗號 , 分隔 - 數(shù)組: 中括號 [] 保存的數(shù)組是值(value)的有序集合. ?個(gè)數(shù)組以左中括號 [ 開始, 右中括號 ] 結(jié)束,值之間使用逗號 , 分隔
傳遞方法:
(1)使用ObjectMapper 對象提供的兩個(gè)方法, 可以完成對象和JSON字符串的互轉(zhuǎn)
????????????writeValueAsString: 把對象轉(zhuǎn)為JSON字符串接
????????????readValue: 把字符串轉(zhuǎn)為對象
(2)接受JSON對象, 需要使用 @RequestBody 注解
原理:賦值是要key=XXX的格式,但是JSON本質(zhì)是一個(gè)字符串,是一整個(gè)數(shù)據(jù),需要轉(zhuǎn)換
二、狀態(tài)碼
- http狀態(tài)碼,不是后端定義的
- 5XX通常指服務(wù)端發(fā)生錯(cuò)誤,4XX通常指客戶端發(fā)生錯(cuò)誤,3XX通常是重定向,2XX通常表示成功
- 業(yè)務(wù)狀態(tài)碼,后端定義的,無法作假
三、其他注解
1. 獲取URL中參數(shù)@PathVariable
@PathVariable:用來獲取url路徑上的數(shù)據(jù)綁定
@RequestMapping("/demo8/{name}/{wendiage}")
public String demo8(@PathVariable String name, @PathVariable("wendiage") Integer age){
return "解析的name:" + name + ", age:" + age;
}
- 查找url的時(shí)候,要準(zhǔn)確對應(yīng)
2. 上傳文件@RequestPart
@RequestMapping("/demo9")
public String demo9(@RequestPart MultipartFile file) throws IOException {
System.out.println(file.getOriginalFilename());
file.transferTo(new File("D:/else/" + file.getOriginalFilename()));
return "success";
}
3. 獲取Cookie/Session
- 傳統(tǒng)獲取方式
- 簡潔注解獲取方式
這兩個(gè)都是會(huì)話機(jī)制
(1) 概念理解
Cookie
Cookie 相當(dāng)于學(xué)生證,注冊完成之后,可以讓保安知道是該學(xué)校的學(xué)生,并完成一系列操作
問題:是可以偽造的
Session
會(huì)話:?個(gè)客戶與服務(wù)器之間的不中斷的請求響應(yīng)
本質(zhì)上是個(gè)“哈希表”,用來存儲用戶的信息,確保服務(wù)器能夠分辨出請求從屬于哪個(gè)對話/用戶
(1)Session是由服務(wù)器生成的唯一的標(biāo)識符。Session 默認(rèn)是保存在內(nèi)存中的. 如果重啟服務(wù)器則 Session 數(shù)據(jù)就會(huì)丟失
(2)Session 是服務(wù)器端的,無法偽造,需要寫代碼手動(dòng)添加。在內(nèi)存中存儲,服務(wù)器重啟后,就會(huì)被清空
(3)問題:分布式情況下,會(huì)多創(chuàng)建Session
Cookie 和 Session 的區(qū)別
- Cookie 是客?端保存??信息的?種機(jī)制,Session 是服務(wù)器端保存??信息的?種機(jī)制
- Cookie 和 Session之間主要是通過 SessionId 關(guān)聯(lián)起來的
- Cookie 和 Session 經(jīng)常會(huì)在?起配合使?. 但是不是必須配合
(2) 獲取Cookie 代碼
Spring 是基于servlet創(chuàng)建的,所以servlet支持的,Spring 都支持
//拿到所有的Cookie
@RequestMapping("/demo10")
public String demo10(HttpServletRequest request, HttpServletResponse response){
//Spring內(nèi)置對象
Cookie[] cookies = request.getCookies();
StringBuilder builder = new StringBuilder();
if (cookies != null){
for (Cookie ck : cookies){
builder.append(ck.getName() + ":" + ck.getValue());
}
}
return "Cookie信息:" + builder;
}
//使用注解的方式,一個(gè)一個(gè)去拿
@RequestMapping("/demo11")
public String cookie(@CookieValue("kunjuan") String bite) {
return "bite:" + bite;
}
Cookie 的值需要設(shè)置,瀏覽器 F12打開開發(fā)者工具,可以手動(dòng)設(shè)置,但也因說明Cookie是可以偽造的, 也就是不安全的, 所以使?Cookie時(shí), 后端需要進(jìn)?Cookie校驗(yàn)
(3) Session 代碼
解析:getSession 內(nèi)部提取到請求中Cookie里的SessionId,然后根據(jù)SessionId獲取到對應(yīng)的Session 對象, Session 對象?HttpSession來描述
Session 存儲:
@RequestMapping("/setSess")
public String setsess(HttpServletRequest request) {
// 獲取Session對象
HttpSession session = request.getSession();
if (session != null) {
session.setAttribute("username", "java");
}
return "session 存儲成功";
}
Session 讀取:
@RequestMapping("/getSess1")
public String sess(HttpServletRequest request) {
// 如果 session 不存在, 不會(huì)?動(dòng)創(chuàng)建
HttpSession session = request.getSession(false);
String username = null;
if (session != null && session.getAttribute("username") != null) {
username = (String) session.getAttribute("username");
}
return "username:" + username;
}
//通過注解只能拿到一個(gè)
@RequestMapping("/getSession2")
public String getSession2(@SessionAttribute(required = false) String username){
//@SessionAttribute 默認(rèn)是一個(gè)必傳參數(shù)
return "username:"+username;
}
@RequestMapping("/getSession3")
public String getSession3(HttpSession session){
String username = (String)session.getAttribute("username");
return "登錄用戶:"+username;
}
//HttpSession session 等同于 HttpSession session = request.getSession(true)
(4) Cookie 和Session 的聯(lián)系
(1)當(dāng)一臺電腦打開了多個(gè)瀏覽器,每一個(gè)瀏覽器對應(yīng)的服務(wù)器都會(huì)創(chuàng)建一個(gè)會(huì)話,但是服務(wù)器之間是不知道這些瀏覽器都是由用戶一個(gè)人打開的,服務(wù)器每一個(gè)會(huì)話都會(huì)記錄一個(gè)SessionId,而每一個(gè)Id都會(huì)對應(yīng)一個(gè)SessionValue,value 里面存了許多值。
(2)后臺服務(wù)器會(huì)把SessionId告訴客戶端,把SessionId存到Cookie里面,后面再訪問的時(shí)候,就會(huì)帶著SessionId去訪問。服務(wù)器就可以根據(jù)SessionId 帶你去拿到這個(gè)SessionId對象
3. 獲取header
@RequestMapping("/getHeader")
public String getHeader(HttpServletRequest request){
String userAgent = request.getHeader("User-Agent");
return "userAgent:"+userAgent;
}
@RequestMapping("/getHeader2")
public String getHeader2(@RequestHeader("User-Agent") String userAgent){
return "userAgent:"+userAgent;
}
四、響應(yīng)操作
- Http響應(yīng)結(jié)果可以是數(shù)據(jù), 也可以是靜態(tài)頁面,也可以針對響應(yīng)設(shè)置狀態(tài)碼, Header信息等
- 多個(gè)注解時(shí), 沒有先后順序, 先寫哪個(gè)都可以
- 響應(yīng)中的 Content-Type 常見取值有以下幾種:
- text/html : body 數(shù)據(jù)格式是 HTML
- text/css : body 數(shù)據(jù)格式是 CSS
- application/javascript : body 數(shù)據(jù)格式是 JavaScript
- application/json : body 數(shù)據(jù)格式是 JSON
1. 返回靜態(tài)頁面
Content-Type 為 text/htm
@RestController
@RequestMapping("/return")
public class returnController {
@RequestMapping("/htmlTest")
public String htmlTest(){
return "/index.html";
}
}
@Controller
@RequestMapping("/return")
public class returnController {
@RequestMapping("/index")
public String htmlTest2(){
return "/index.html";
}
}
(1)解析
@RestController
@RestController 定義返回的數(shù)據(jù)格式為非視圖, 返回?個(gè) text/html 信息,即返回的是正文信息
@Controller
@Controller 定義?個(gè)控制器, Spring 框架啟動(dòng)時(shí)加載, 把這個(gè)對象交給Spring管理
ResponseBody
@ResponseBody,定義返回的數(shù)據(jù)格式為?視圖, 返回?個(gè) text/html 信息
生命周期:活在代碼里,編譯后,就消失了
2. 返回?cái)?shù)據(jù)
可以修飾類,也可以修飾方法。修飾類的時(shí)候,表示這個(gè)類下的所有方法,返回的均為數(shù)據(jù),修飾方法時(shí),表示該方法返回的是數(shù)據(jù)
@ResponseBody
@RequestMapping("/index2")
public String htmlTest3(){
return "/index.html";
}
Content-Type 為 text/htm
3. 返回HTML代碼片段
@ResponseBody
@RequestMapping("/returnHtml")
public String returnHtml(){
return "<h1>返回HTML代碼片段</h1>";
}
Content-Type 為 text/htm
4. 返回JSON
當(dāng)方法返回的數(shù)據(jù)是對象/map等時(shí),SpringMVC會(huì)自動(dòng)設(shè)置返回的 content-type 為 application/json
@ResponseBody
@RequestMapping("/returnJson")
public Person returnJson(){
Person person = new Person();
person.setId(1);
person.setName("zhangsan");
person.setAge(7);
return person;
}
5. 設(shè)置狀態(tài)碼
Spring MVC會(huì)根據(jù)我們方法的返回結(jié)果自動(dòng)設(shè)置響應(yīng)狀態(tài)碼, 程序員也可以手動(dòng)指定狀態(tài)碼,這個(gè)狀態(tài)碼指的是http狀態(tài)碼
@ResponseBody
@RequestMapping("/setStatus")
public String setStatus(HttpServletResponse response){
response.setStatus(401);//通常表示沒有登錄
return "設(shè)置狀態(tài)碼";
}
6. 設(shè)置header
@ResponseBody
@RequestMapping(value = "/r1",produces = "application/json;charset=utf-8")
public String r1(HttpServletResponse response){
//設(shè)置header
response.setHeader("myhead","myhead");
return "{'OK':1}";
}
- consumes:限制能夠處理的請求,不是這個(gè)請求的處理不了
- produces:設(shè)置返回的內(nèi)容類型
五、lombok介紹
Lombok是?個(gè)Java工具庫,通過添加注解的方式,簡化Java的開發(fā)。注解可以幫助我們消除?些冗長代碼, 使代碼看起來簡潔?些
1. 原理
反編譯是將可執(zhí)行的程序代碼轉(zhuǎn)換為某種形式的高級編程語言(把字節(jié)碼文件轉(zhuǎn)為代碼), 使其具有更易讀的格式. 反編譯是?種逆向工程,它的作用與編譯器的作用相反
2. 使用
@Data = @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor + @NoArgsConstructor
注解 | 作用 |
---|---|
@Getter | 自動(dòng)添加 getter 方法 |
@Setter | 自動(dòng)添加 setter 方法 |
@ToString | 自動(dòng)添加 toString 方法 |
@EqualsAndHashCode | ?動(dòng)添加 equals 和 hashCode 方法 |
@NoArgsConstructor | 自動(dòng)添加?參構(gòu)造方法 |
@AllArgsConstructor | 自動(dòng)添加全屬性構(gòu)造?法,順序按照屬性的定義順序 |
@NonNull | 屬性不能為 null |
@RequiredArgsConstructor | 自動(dòng)添加必需屬性的構(gòu)造方法,final + @NonNull 的屬性為必需 |
六、應(yīng)用分層
類似于公司的組織架構(gòu),可以有效地避免代碼冗雜、擴(kuò)展性差等問題。MVC就是一種拆分方式,但是隨著前后端的分離,后端開發(fā)又有了新的分層方式
1. 分層架構(gòu)
新的分層架構(gòu):把整體架構(gòu)分為表現(xiàn)層、業(yè)務(wù)邏輯層和數(shù)據(jù)層。這種分層方式也稱之為"三層架構(gòu)".
- 表現(xiàn)層: 就是展示數(shù)據(jù)結(jié)果和接受用戶指令的,是最靠近用戶的?層;
- 業(yè)務(wù)邏輯層: 負(fù)責(zé)處理業(yè)務(wù)邏輯, 里面有復(fù)雜業(yè)務(wù)的具體實(shí)現(xiàn);
- 數(shù)據(jù)層: 負(fù)責(zé)存儲和管理與應(yīng)用程序相關(guān)的數(shù)據(jù)
這三個(gè)部分在 spring 中的體現(xiàn):文章來源:http://www.zghlxwxcb.cn/news/detail-735571.html
- Controller:控制層。接收前端發(fā)送的請求,對請求進(jìn)?處理,并響應(yīng)數(shù)據(jù)。
- Service:業(yè)務(wù)邏輯層。處理具體的業(yè)務(wù)邏輯。
- Dao:數(shù)據(jù)訪問層,也稱為持久層。負(fù)責(zé)數(shù)據(jù)訪問操作,包括數(shù)據(jù)的增、刪、改、查
七、企業(yè)規(guī)范
以下是適用于多數(shù)企業(yè)的規(guī)范文章來源地址http://www.zghlxwxcb.cn/news/detail-735571.html
- 類名使用大駝峰風(fēng)格,但以下情形例外:DO/BO/DTO/VO/AO
- 方法名、參數(shù)名、成員變量、局部變量統(tǒng)?使用小駝峰風(fēng)格
- 包名統(tǒng)?使用小寫,點(diǎn)分隔符之間有且僅有?個(gè)自然語義的英語單詞
到了這里,關(guān)于Spring Boot Web MVC的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!