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執行原理

 

 簡要分析執行流程:

  1. DispatcherServlet表示前置控制器,是整個SpringMVC的控制中心。用戶發出請求,DispatcherServlet接收請求並攔截請求。

  2. HandlerMapping為處理器映射。DispatcherServlet調用HandlerMapping,HandlerMapping根據請求url查找Handler。

  3. HandlerExecution表示具體的Handler,其主要作用是根據url查找控制器,如上url被查找控制器為:hello。

  4. HandlerExecution將解析後的信息傳遞給DispatcherServlet,如解析控制器映射等。

  5. HandlerAdapter表示處理器適配器,其按照特定的規則去執行Handler。

  6. Handler讓具體的Controller執行。

  7. Controller將具體的執行信息返回給HandlerAdapter,如ModelAndView。

  8. HandlerAdapter將視圖邏輯名或模型傳遞給DispatcherServlet。

  9. DispatcherServlet調用視圖解析器(ViewResolver)來解析HandlerAdapter傳遞的邏輯視圖名。

  10. 視圖解析器將解析的邏輯視圖名傳給DispatcherServlet。

  11. DispatcherServlet根據視圖解析器解析的視圖結果,調用具體的視圖。

  12. 最終視圖呈現給用戶。

註解開發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>

小結

實現步驟其實非常的簡單:

  1. 新建一個web項目

  2. 導入相關jar包

  3. 編寫web.xml , 註冊DispatcherServlet

  4. 編寫springmvc配置文件

  5. 接下來就是去創建對應的控制類 , controller

  6. 最後完善前端視圖和controller之間的對應

  7. 測試運行調試.

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框架的整合

 



Tags: