SpringMVC學習筆記(一)
什麼是SpringMVC
Spring MVC是Spring Framework的一部分,是基於Java實現MVC的輕量級Web框架。
查看官方文檔://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web
Spring的web框架圍繞DispatcherServlet [ 調度Servlet ] 設計。
DispatcherServlet的作用是將請求分發到不同的處理器
SpringMVC執行原理
簡要分析執行流程:
-
DispatcherServlet表示前置控制器,是整個SpringMVC的控制中心。用戶發出請求,DispatcherServlet接收請求並攔截請求。
-
HandlerMapping為處理器映射。DispatcherServlet調用HandlerMapping,HandlerMapping根據請求url查找Handler。
-
HandlerExecution表示具體的Handler,其主要作用是根據url查找控制器,如上url被查找控制器為:hello。
-
HandlerExecution將解析後的信息傳遞給DispatcherServlet,如解析控制器映射等。
-
HandlerAdapter表示處理器適配器,其按照特定的規則去執行Handler。
-
Handler讓具體的Controller執行。
-
Controller將具體的執行信息返回給HandlerAdapter,如ModelAndView。
-
HandlerAdapter將視圖邏輯名或模型傳遞給DispatcherServlet。
-
DispatcherServlet調用視圖解析器(ViewResolver)來解析HandlerAdapter傳遞的邏輯視圖名。
-
視圖解析器將解析的邏輯視圖名傳給DispatcherServlet。
-
DispatcherServlet根據視圖解析器解析的視圖結果,調用具體的視圖。
-
最終視圖呈現給用戶。
註解開發MVC
配置web.xml
註冊DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="//xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="//xmlns.jcp.org/xml/ns/javaee //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】
添加Spring MVC配置文件
在resource目錄下添加springmvc-servlet.xml配置文件,配置的形式與Spring容器配置基本類似,為了支持基於註解的IOC,設置了自動掃描包的功能,具體配置信息如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="//www.springframework.org/schema/beans" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:context="//www.springframework.org/schema/context" xmlns:mvc="//www.springframework.org/schema/mvc" xsi:schemaLocation="//www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd //www.springframework.org/schema/context //www.springframework.org/schema/context/spring-context.xsd //www.springframework.org/schema/mvc //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
@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 風格
使用RESTful操作資源 :
可以通過不同的請求方式來實現不同的效果!如下:請求地址一樣,但是功能可以不同!
//127.0.0.1/item/1 查詢,GET
//127.0.0.1/item 新增,POST
//127.0.0.1/item 更新,PUT
//127.0.0.1/item/1 刪除,DELETE
測試使用
@PathVariable 註解
在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"; }
使用method屬性指定請求類型
用於約束請求的類型,可以收窄請求範圍。指定請求謂詞的類型如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為另一個請求/ } }
數據處理
處理提交數據
1、提交的域名稱和處理方法的參數名一致
提交數據 : //localhost:8080/hello?name=kuangshen
處理方法 :
@RequestMapping("/hello") public String hello(String name){ System.out.println(name); return "hello"; }
2、提交的域名稱和處理方法的參數名不一致
提交數據 : //localhost:8080/hello?username=kuangshen
處理方法 :
//@RequestParam("username") : username提交的域的名稱 . @RequestMapping("/hello") public String hello(@RequestParam("username") String name){ System.out.println(name); return "hello"; }
3、提交的是一個對象
要求提交的表單域和對象的屬性名一致 , 參數使用對象即可
1、實體類
public class User { private int id; private String name; private int age; //構造 //get/set //tostring() }
2、提交數據 : //localhost:8080/mvc04/user?name=kuangshen&id=1&age=15
3、處理方法 :
@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框架的整合