Spring MVC是Spring Framework的一部分,是基於Java實現MVC的輕量級Web框架。
html
查看官方文檔:https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web前端
Spring的web框架圍繞DispatcherServlet [ 調度Servlet ] 設計。java
DispatcherServlet的做用是將請求分發到不一樣的處理器web
簡要分析執行流程:spring
DispatcherServlet表示前置控制器,是整個SpringMVC的控制中心。用戶發出請求,DispatcherServlet接收請求並攔截請求。瀏覽器
HandlerMapping爲處理器映射。DispatcherServlet調用HandlerMapping,HandlerMapping根據請求url查找Handler。spring-mvc
HandlerExecution表示具體的Handler,其主要做用是根據url查找控制器,如上url被查找控制器爲:hello。安全
HandlerExecution將解析後的信息傳遞給DispatcherServlet,如解析控制器映射等。服務器
HandlerAdapter表示處理器適配器,其按照特定的規則去執行Handler。mvc
Handler讓具體的Controller執行。
Controller將具體的執行信息返回給HandlerAdapter,如ModelAndView。
HandlerAdapter將視圖邏輯名或模型傳遞給DispatcherServlet。
DispatcherServlet調用視圖解析器(ViewResolver)來解析HandlerAdapter傳遞的邏輯視圖名。
視圖解析器將解析的邏輯視圖名傳給DispatcherServlet。
DispatcherServlet根據視圖解析器解析的視圖結果,調用具體的視圖。
最終視圖呈現給用戶。
註冊DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--1.註冊servlet--> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--經過初始化參數指定SpringMVC配置文件的位置,進行關聯--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!-- 啓動順序,數字越小,啓動越早 --> <load-on-startup>1</load-on-startup> </servlet> <!--全部請求都會被springmvc攔截 --> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
/ 和 /* 的區別:
< url-pattern > / </ url-pattern > 不會匹配到.jsp, 只針對咱們編寫的請求;即:.jsp 不會進入spring的 DispatcherServlet類 。
< url-pattern > /* </ url-pattern > 會匹配 *.jsp,會出現返回 jsp視圖 時再次進入spring的DispatcherServlet 類,致使找不到對應的controller因此報404錯。
注意web.xml版本問題,要最新版!
註冊DispatcherServlet
關聯SpringMVC的配置文件
啓動級別爲1
映射路徑爲 / 【不要用/*,會404】
在resource目錄下添加springmvc-servlet.xml配置文件,配置的形式與Spring容器配置基本相似,爲了支持基於註解的IOC,設置了自動掃描包的功能,具體配置信息以下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自動掃描包,讓指定包下的註解生效,由IOC容器統一管理 --> <context:component-scan base-package="com.kuang.controller"/> <!-- 讓Spring MVC不處理靜態資源 --> <mvc:default-servlet-handler /> <!-- 支持mvc註解驅動 在spring中通常採用@RequestMapping註解來完成映射關係 要想使@RequestMapping註解生效 必須向上下文中註冊DefaultAnnotationHandlerMapping 和一個AnnotationMethodHandlerAdapter實例 這兩個實例分別在類級別和方法級別處理。 而annotation-driven配置幫助咱們自動完成上述兩個實例的注入。 --> <mvc:annotation-driven /> <!-- 視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!-- 前綴 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 後綴 --> <property name="suffix" value=".jsp" /> </bean> </beans>
在視圖解析器中咱們把全部的視圖都存放在/WEB-INF/目錄下,這樣能夠保證視圖安全,由於這個目錄下的文件,客戶端不能直接訪問。
@Controller @RequestMapping("/HelloController") public class HelloController { //真實訪問地址 : 項目名/HelloController/hello @RequestMapping("/hello") public String sayHello(Model model){ //向模型中添加屬性msg與值,能夠在JSP頁面中取出並渲染 model.addAttribute("msg","hello,SpringMVC"); //web-inf/jsp/hello.jsp return "hello"; } }
@Controller是爲了讓Spring IOC容器初始化時自動掃描到;
@RequestMapping是爲了映射請求路徑,這裏由於類與方法上都有映射因此訪問時應該是/HelloController/hello;
方法中聲明Model類型的參數是爲了把Action中的數據帶到視圖中;
方法返回的結果是視圖的名稱hello,加上配置文件中的先後綴變成WEB-INF/jsp/hello.jsp。
在WEB-INF/ jsp目錄中建立hello.jsp , 視圖能夠直接取出並展現從Controller帶回的信息;
能夠經過EL表示取出Model中存放的值,或者對象;
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>SpringMVC</title> </head> <body> ${msg} </body> </html>
實現步驟其實很是的簡單:
新建一個web項目
導入相關jar包
編寫web.xml , 註冊DispatcherServlet
編寫springmvc配置文件
接下來就是去建立對應的控制類 , controller
最後完善前端視圖和controller之間的對應
測試運行調試.
使用RESTful操做資源 :
能夠經過不一樣的請求方式來實現不一樣的效果!以下:請求地址同樣,可是功能能夠不一樣!
http://127.0.0.1/item/1 查詢,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 刪除,DELETE
在Spring MVC中能夠使用 @PathVariable 註解,讓方法參數的值對應綁定到一個URI模板變量上。
@Controller public class RestFulController { //映射訪問路徑 @RequestMapping("/commit/{p1}/{p2}") public String index(@PathVariable int p1, @PathVariable int p2, Model model){ int result = p1+p2; //Spring MVC會自動實例化一個Model對象用於向視圖中傳值 model.addAttribute("msg", "結果:"+result); //返回視圖位置 return "test"; } }
咱們來修改下對應的參數類型,再次測試
@RequestMapping("/commit/{p1}/{p2}") public String index(@PathVariable int p1, @PathVariable String p2, Model model){ String result = p1+p2; //Spring MVC會自動實例化一個Model對象用於向視圖中傳值 model.addAttribute("msg", "結果:"+result); //返回視圖位置 return "test"; }
用於約束請求的類型,能夠收窄請求範圍。指定請求謂詞的類型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
例如:
//映射訪問路徑,必須是POST請求 @RequestMapping(value = "/hello",method = {RequestMethod.POST}) public String index2(Model model){ model.addAttribute("msg", "hello!"); return "test"; }
若是咱們使用瀏覽器地址欄進行訪問默認是Get請求,會報錯405:
也能夠經過註解處理 HTTP 請求的方法:@GetMapping;@PostMapping;@PutMapping;@DeleteMapping;@PatchMapping,效果是同樣的
@GetMapping("/add/{a}/{b}") public String test(@PathVariable int a,@PathVariable String b, Model model) { String res=a+b; model.addAttribute("msg","get結果爲"+res); return "test"; } @PostMapping("/add/{a}/{b}") public String test2(@PathVariable int a,@PathVariable String b, Model model) { String res=a+b; model.addAttribute("msg","method方法結果爲"+res); return "test"; }
@Controller public class ResultSpringMVC2 { @RequestMapping("/rsm2/t1") public String test1(){ //轉發 return "test"; } @RequestMapping("/rsm2/t2") public String test2(){ //重定向 return "redirect:/index.jsp"; //return "redirect:hello.do"; //hello.do爲另外一個請求/ } }
一、提交的域名稱和處理方法的參數名一致
提交數據 : http://localhost:8080/hello?name=kuangshen
處理方法 :
@RequestMapping("/hello") public String hello(String name){ System.out.println(name); return "hello"; }
二、提交的域名稱和處理方法的參數名不一致
提交數據 : http://localhost:8080/hello?username=kuangshen
處理方法 :
//@RequestParam("username") : username提交的域的名稱 . @RequestMapping("/hello") public String hello(@RequestParam("username") String name){ System.out.println(name); return "hello"; }
三、提交的是一個對象
要求提交的表單域和對象的屬性名一致 , 參數使用對象便可
一、實體類
public class User { private int id; private String name; private int age; //構造 //get/set //tostring() }
二、提交數據 : http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15
三、處理方法 :
@RequestMapping("/user") public String user(User user){ System.out.println(user); return "hello"; }
經過Model
@RequestMapping("/ct2/hello") public String hello(@RequestParam("username") String name, Model model){ //封裝要顯示到視圖中的數據 //至關於req.setAttribute("name",name); model.addAttribute("msg",name); System.out.println(name); return "test"; }
經過ModelAndView
public class ControllerTest1 implements Controller { public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { //返回一個模型視圖對象 ModelAndView mv = new ModelAndView(); mv.addObject("msg","ControllerTest1"); mv.setViewName("test"); return mv; } }
經過ModelMap
@RequestMapping("/hello") public String hello(@RequestParam("username") String name, ModelMap model){ //封裝要顯示到視圖中的數據 //至關於req.setAttribute("name",name); model.addAttribute("name",name); System.out.println(name); return "hello"; }
輸入中文測試,發現亂碼
SpringMVC給咱們提供了一個過濾器 , 能夠在web.xml中配置 .
修改了xml文件須要重啓服務器!
<filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
明天任務:進行ssm框架的整合