目錄
Spring Web MVC 是什么
什么是Serlet
什么是MVC
什么是Spring MVC
使用Spring MVC
建立連接
@RequestMapping
請(qǐng)求
傳遞單個(gè)參數(shù)
傳遞多個(gè)參數(shù)
傳遞對(duì)象
后端參數(shù)重命名
?傳遞數(shù)組
傳遞集合
傳遞JSON數(shù)據(jù)
獲取url參數(shù)-@pathvariable
上傳文件@RequestPart
獲取Cookie
Session
獲取Header
響應(yīng)
返回靜態(tài)頁面
返回HTML代碼片段
返回JSON
設(shè)置狀態(tài)碼
設(shè)置Header
應(yīng)用分層
如何分層
MVC與三層架構(gòu)的區(qū)別和聯(lián)系
?
Spring Web MVC 是什么
Sring Web MVC就是基于 Serlet API構(gòu)建的Web框架. 它從一開始就包含在Spring框架中. 也可以簡(jiǎn)稱Spring MVC
什么是Serlet
Serlet它是一種實(shí)現(xiàn)動(dòng)態(tài)頁面的技術(shù).說準(zhǔn)確一點(diǎn)Serlet就是一套Java Web開發(fā)的規(guī)范,或者是技術(shù)標(biāo)準(zhǔn). 它是不能去做任何事情的,需要有人去實(shí)現(xiàn)這套開發(fā)規(guī)范. 實(shí)現(xiàn)這套開發(fā)規(guī)范就是真正的去編寫代碼實(shí)現(xiàn)里面提到的各種功能,包括類,方法,屬性.這套規(guī)范sun公司是開放的,其他公司也可以實(shí)現(xiàn)這套規(guī)范.現(xiàn)在常用的Serlet產(chǎn)品有Tomcat,Weblogic,Jetty等,它們都可以叫做Serlet容器.Serlet容器就是用來管理程序猿編寫的serlet類.我們Spring boot中就是內(nèi)置了Tomcat.
什么是MVC
MVC它是軟件工程中的一種軟件架構(gòu)設(shè)計(jì)的模式. 它把軟件系統(tǒng)分為模型,視圖,控制器三個(gè)部分.
視圖: 在應(yīng)用程序這中用來和瀏覽器進(jìn)行交互,展現(xiàn)數(shù)據(jù)資源.
模型: 用來處理程序中數(shù)據(jù)邏輯的部分.
控制器: 它用來決定對(duì)于視圖發(fā)來的請(qǐng)求,需要用哪一個(gè)模型來處理,以及處理完后需要跳轉(zhuǎn)回哪個(gè)視圖.就是用來連接視圖和模型的.
這就類似于去海底撈吃火鍋:
進(jìn)去服務(wù)器來接待客戶點(diǎn)餐,點(diǎn)完餐后將菜單交給前廳,前廳再根據(jù)菜單要求給后廚發(fā)出指令,后廚就負(fù)責(zé)準(zhǔn)備菜. 準(zhǔn)備好后,前廳再告訴服務(wù)器這是為x號(hào)桌準(zhǔn)備的.
服務(wù)器就是視圖,前廳就是控制器,后廚就是模型.
什么是Spring MVC
MVC是一種構(gòu)架設(shè)計(jì)模式,也是一種思想,而Spring MVC就是對(duì)MVC思想的具體實(shí)現(xiàn). 除此之外,Spring MVC還是一個(gè)Web框架,所以Spring MVC是一個(gè)實(shí)現(xiàn)了MVC思想的web框架. 而Spring boot將Spring MVC給集成進(jìn)去了. 且Spring在實(shí)現(xiàn)MVC的時(shí)候,也做出了一些自己的改變. 請(qǐng)求會(huì)直接到達(dá)控制器,讓控制器來處理.
這就和飯店吃飯,有的地方是前廳來負(fù)責(zé)接待客人,幫助客人點(diǎn)餐,也就是Controller來負(fù)責(zé)接收客戶的請(qǐng)求.
使用Spring MVC
因?yàn)槭莣eb框架,我們?cè)跒g覽器中輸入url后,我們的Spring MVC項(xiàng)目就可以感應(yīng)到用戶的請(qǐng)求,且給予相應(yīng).
所以我們學(xué)習(xí)Spring MVC,也就是學(xué)習(xí)如何通過游覽器和用戶程序進(jìn)行交互.分為三個(gè)方面:
建立連接: 將客戶端和Java程序連接起來,訪問一個(gè)地址可以調(diào)用到我們的Spring程序.
請(qǐng)求: 用戶請(qǐng)求時(shí),會(huì)攜帶一些參數(shù),在程序中我們就要想辦法獲取到這些參數(shù).?
響應(yīng): 執(zhí)行邏輯后,就要把執(zhí)行的結(jié)果返回給用戶.
掌握了這三個(gè)功能,就掌握了Spring MVC.
建立連接
在Spring MVC中,我們使用@RequestMapping來實(shí)現(xiàn)yur路由映射,也就是瀏覽器連接程序的作用.
代碼實(shí)現(xiàn):
import org.springframework.web.bind.annotation.*;
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/sayHi")
public String say1() {
return "hello, SpringMVC";
}
訪問http://127.0.0.1:8080/say/sayHi就可以看到hello,SpringMVC了.
@RequestMapping
它是Spring MVC中常用的一種注解,它是用來注冊(cè)接口的路由映射的. 當(dāng)服務(wù)接收到請(qǐng)求時(shí),路徑為sayHi的請(qǐng)求就會(huì)調(diào)用sayHi這個(gè)方法的代碼. 加上@RestConteoller,Spring才會(huì)去看這個(gè)類中方法有沒有加@RequestMapping這個(gè)注解. 且@RequestMapping即可修飾類,也可以修飾方法. 訪問的地址是類路徑+方法路徑.?@RequestMapping各種請(qǐng)求類型都可以使用.
@RequestMapping標(biāo)識(shí)類: 表示設(shè)置映射請(qǐng)求的請(qǐng)求路徑的初始信息.
@RequestMapping標(biāo)識(shí)方法: 表示設(shè)置映射請(qǐng)求路徑的具體信息.
路由映射:當(dāng)用戶訪問uer時(shí),將用戶的請(qǐng)求對(duì)應(yīng)到應(yīng)用程序中某個(gè)類的某個(gè)方法的過程就叫做路由映射.
請(qǐng)求
訪問不同路徑,就是發(fā)送不同的參數(shù).在發(fā)送請(qǐng)求的同時(shí),可能會(huì)帶一些參數(shù),我們需要知道如何傳遞參數(shù)到后端以及如何接受.
傳遞單個(gè)參數(shù)
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r11/{name}")
public String r1(String username) {
return "name: " + username;
}
注意:
url和參數(shù)名稱不一致,是拿不到值的.?
使用基本類型來接收參數(shù),參數(shù)必須傳,不然會(huì)報(bào)500錯(cuò)誤.類型不匹配會(huì)報(bào)400錯(cuò)誤,對(duì)于參數(shù)為空的數(shù)據(jù),建議使用包裝類型.
傳遞多個(gè)參數(shù)
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r3")
public String say3(Integer age, String name, Integer id) {
return "接收到: " + age + name + id;
}
}
當(dāng)有多個(gè)參數(shù)時(shí),前后端進(jìn)行匹配時(shí)按照參數(shù)的名稱來進(jìn)行匹配的,所以位置不影響后端獲取參數(shù)的結(jié)果.
傳遞對(duì)象
package com.example.demo;
import lombok.Data;
@Data
public class Student {
private String name;
private Integer age;
private int Id;
}
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r4")
public String say4(Student student) {
return "接收到: " + student;
}
}
Spring會(huì)根據(jù)參數(shù)名稱來自動(dòng)綁定到對(duì)象的各個(gè)屬性中,如果某個(gè)參數(shù)沒傳遞,則賦值為null,基本類型為默認(rèn)值.
后端參數(shù)重命名
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r6")
public String say5(@RequestParam("name") String uername) {
return uername;
}
}
使用@RequestParam進(jìn)行參數(shù)重命名時(shí),請(qǐng)求參數(shù)只能和@RequestParam聲明的名稱一致,才能進(jìn)行參數(shù)綁定和賦值.且使用@RequestParam后參數(shù)變成了必傳參數(shù).(它的required默認(rèn)為true)
?傳遞數(shù)組
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r8")
public String say8(String[] array) {
return Arrays.toString(array);
}
}
傳遞集合
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r9")
public String r9(@RequestParam() List<String> list) {
return "list:" +list;
}
}
集合參數(shù)和數(shù)組類似,同一個(gè)請(qǐng)求參數(shù)名有多個(gè),且需要使用@RequestParam來綁定參數(shù)關(guān)系(默認(rèn)情況下,請(qǐng)求中參數(shù)名相同的多個(gè)值是封裝到數(shù)組中的)
傳遞JSON數(shù)據(jù)
json的數(shù)據(jù)是在鍵值對(duì)key和value中,數(shù)據(jù)用,分割 對(duì)象用{}, 數(shù)組用[]表示 值可以為對(duì)象,也可以為數(shù)組,數(shù)組中可以有多個(gè)對(duì)象.
@RequestBody:表示請(qǐng)求正文, 意思是這個(gè)注解作用在請(qǐng)求正文的數(shù)據(jù)綁定,請(qǐng)求參數(shù)必須寫在請(qǐng)求正文中.
@RequestMapping("/r10")
public String r10(@RequestBody Student student) {
return "接收到: " + student;
}
獲取url參數(shù)-@pathvariable
@pathvariable: 路徑變量
這個(gè)注解作用就是將請(qǐng)求url路徑上的數(shù)據(jù)綁定,默認(rèn)是傳遞參數(shù)寫在url上,SpringMVC就可以獲取到
@RequestMapping("/r11/{name}")
public String r11(@PathVariable("name") String username) {
return "name: " + username;
}
上傳文件@RequestPart
@RequestMapping("/say")
@RestController
public class Requst {
@RequestMapping("/r12")
public String r12(@RequestPart("filename") MultipartFile file) {
String filename = file.getOriginalFilename();
return "file: " + filename;
}
}
獲取Cookie
傳統(tǒng)獲取cookie:
@RequestMapping("/getc")
public String getCookie(HttpServletRequest request) {
String name = request.getParameter("name");
Cookie[] cookkies = request.getCookies();
StringBuilder builder = new StringBuilder();
if (cookkies!=null){
for (Cookie ck:cookkies) {
builder.append(ck.getName()+":"+ck.getValue());
}
}
return "Cookie: " + builder;
}
HttpServletRequest,HttpServletResponse是Servlet提供的兩個(gè)類,是SpringMVC的內(nèi)置對(duì)象(因?yàn)镾pring MVC是基于Servlet進(jìn)一步封建的),需要使用時(shí)直接聲明即可.
簡(jiǎn)易獲取Cookie:
@RequestMapping("/getc1")
public String getCookie1(@CookieValue("bite") String bite) {
return "Cookie: " + bite;
}
Session
Session存儲(chǔ)
@RequestMapping("/setc")
public String setsess(HttpServletRequest request) {
//getSession()是通過request中的Cookie中的SessionID來獲取到對(duì)應(yīng)的Session對(duì)象.
HttpSession session = request.getSession();
session.setAttribute("name", "zhangsan");
session.setAttribute("n", "zhang");
return "設(shè)置成功";
}
獲取Session的兩種方式:
HttpSession getSession(boolean create);
HttpSession getSession();
getSession(boolean create): 參數(shù)如果為True,則不存在會(huì)話時(shí)會(huì)創(chuàng)建新的會(huì)話;參數(shù)如果為false,則當(dāng)不存在會(huì)話時(shí)返回null.
getSession(): 和getSession(true)含義一樣,默認(rèn)值為true;
Object getAttribute(String name)
返回Session會(huì)話中具有指定名稱的對(duì)象,如果沒有,返回null.
簡(jiǎn)易獲取Session
@RequestMapping("/getSess2")
public String sess2(@SessionAttribute(value = "username",required = false)
String username) {
return "username:"+username;
}
@RequestMapping("/getSess3")
public String sess3(HttpSession session) {
String username = (String)session.getAttribute("username");
return "username:"+username;
}
獲取Header
傳統(tǒng)獲取Header:
@RequestMapping("/param10")
public String param10(HttpServletRequest request, HttpServletResponse response)
{
String userAgent = request.getHeader("User-Agent");
return name + ":"+userAgent;
}
簡(jiǎn)易獲取Header:
@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
return "userAgent:"+userAgent;
}
RequestHeader的參數(shù)值為HTTP請(qǐng)求報(bào)頭中的Key.
響應(yīng)
Http相應(yīng)結(jié)果可以是數(shù)據(jù),也可以是靜態(tài)頁面,也可以針對(duì)響應(yīng)設(shè)置狀態(tài)碼,Header信息等.
返回靜態(tài)頁面
我們需要將前端頁面放在static包下.
后端代碼訪問:
@Controller
public class ResponseController {
@RequestMapping("/index")
public Object index() {
return "/index.html";
}
注意:
@RestController = Controller + ResponseBody
@Controller: 定義一個(gè)控制器, Spring框架啟動(dòng)時(shí)加載,把這個(gè)對(duì)象交給Spring管理
@ResponseBody: 定義返回的數(shù)據(jù)格式為非視圖,返回一個(gè)text/html信息.它即可以在類上,也可以在方法上.
想要返回視圖用@Controller即可.
返回HTML代碼片段
后端返回?cái)?shù)據(jù)時(shí),如果數(shù)據(jù)中有HTML代碼,也會(huì)被游覽器解析:
@Controller
public class ResponseController {
@ResponseBody
@RequestMapping("/returnhtml")
public String returnhtml() {
return "<H1>我是index頁面</H1>";
}
}
返回JSON
Spring MVC也可以返回JSON,后端方法返回結(jié)果為對(duì)象:
@ResponseBody
@RequestMapping("/returnjson")
public HashMap<String, String> returnjson() {
HashMap<String, String> hash = new HashMap<>();
hash.put("java", "110");
hash.put("mysql", "110");
return hash;
}
設(shè)置狀態(tài)碼
SpringMVC會(huì)根據(jù)我們的方法返回結(jié)果自動(dòng)設(shè)置響應(yīng)狀態(tài)碼,但也可以手動(dòng)指定狀態(tài)碼.
@ResponseBody
@RequestMapping("/setstatus")
public Object setstatus(HttpServletResponse response) {
response.setStatus(404);
return "666";
}
設(shè)置Header
Http相應(yīng)報(bào)頭會(huì)向客戶端傳遞一些附加信息,比如服務(wù)程序的名稱,請(qǐng)求的資源已移動(dòng)到新地址等.這些信息通過@RequestMapping注解的屬性來實(shí)現(xiàn).
@RequestMapping源碼:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
@Reflective({ControllerMappingReflectiveProcessor.class})
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
1. value: 指定映射的URL
2. method:指定請(qǐng)求的method類型, 如GET,POST等
3. consumes: 指定處理請(qǐng)求(request)的提交內(nèi)容類型(Content-Type),例如application/json,
text/html;
4. produces: 指定返回的內(nèi)容類型,僅當(dāng)request請(qǐng)求頭中的(Accept)類型中包含該指定類型才返回?
5. Params:指定request中必須包含某些參數(shù)值時(shí),才讓該?法處理
6. headers:指定request中必須包含某些指定的header值,才能讓該?法處理請(qǐng)求?
設(shè)置Content-Type
@RequestMapping(value = "/returnJson2",produces = "application/json")
@ResponseBody
public String returnJson2() {
return "{\"success\":true}";
}
設(shè)置其他Header
這需要使用HttpServletResPonse提供的方法來進(jìn)行設(shè)置:
@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
response.setHeader("MyHeader","MyHeaderValue");
return "設(shè)置Header成功";
}
應(yīng)用分層
應(yīng)用分層是一種設(shè)計(jì)思想,它是將應(yīng)用程序分為N個(gè)層次,分別負(fù)責(zé)各自的職責(zé),MVC設(shè)計(jì)模式就是分層的具體體現(xiàn).
如何分層
這里我們將整體分為三個(gè)層次,將用戶視圖和業(yè)務(wù)隔離開來,通過控制器連接起來,可以很好的視線邏輯的解耦.現(xiàn)在流行的開發(fā)發(fā)方式是前后端分離的方式,后端開發(fā)工程師不需要關(guān)注前端的實(shí)現(xiàn),我們Java后端又有了一種新的分層架構(gòu): 把整體架構(gòu)分為表現(xiàn)層,業(yè)務(wù)邏輯層,數(shù)據(jù)層,這種分層方式稱為"三層架構(gòu)".
表現(xiàn)層(Controller): 展現(xiàn)數(shù)據(jù)結(jié)果和接受用戶指令.
業(yè)務(wù)邏輯層(Service): 負(fù)責(zé)處理業(yè)務(wù)邏輯
數(shù)據(jù)層(Dao): 負(fù)責(zé)存儲(chǔ)管理與應(yīng)用相關(guān)的數(shù)據(jù).
在編寫代碼時(shí),我們就可以分為三個(gè)包來具體實(shí)現(xiàn)三層架構(gòu):
model是用來放實(shí)體類的.
MVC與三層架構(gòu)的區(qū)別和聯(lián)系
這兩者可以說都是軟件工程中的架構(gòu)模式.
MVC中視圖和控制器合起來對(duì)應(yīng)的是三層架構(gòu)中的表現(xiàn)層,模型對(duì)應(yīng)的就是三層架構(gòu)中的業(yè)務(wù)層,數(shù)據(jù)層,實(shí)體類.
這兩者是從不同角度進(jìn)行了抽象:
MVC強(qiáng)調(diào)的是數(shù)據(jù)和視圖分離,將數(shù)據(jù)展示和數(shù)據(jù)處理分開,通過控制器對(duì)兩者組合.而三層架構(gòu)搶到的是不同維度數(shù)據(jù)處理的高內(nèi)聚和低耦合,將業(yè)務(wù)處理,數(shù)據(jù)庫,交互頁面的邏輯分開.文章來源:http://www.zghlxwxcb.cn/news/detail-848423.html
但是它們兩者的目的都是一樣的,都是解耦,分層,代碼復(fù)用.文章來源地址http://www.zghlxwxcb.cn/news/detail-848423.html
到了這里,關(guān)于【JavaEE】Spring Web-MVC的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!