SpringMVC學習筆記(一)

清風紫雪發表於2020-12-26

什麼是SpringMVC

Spring MVC是Spring Framework的一部分,是基於Java實現MVC的輕量級Web框架。

檢視官方文件:https://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="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】

新增Spring MVC配置檔案

在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

@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操作資源

可以通過不同的請求方式來實現不同的效果!如下:請求地址一樣,但是功能可以不同!

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

測試使用

@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、提交的域名稱和處理方法的引數名一致

提交資料 : http://localhost:8080/hello?name=kuangshen

處理方法 :

@RequestMapping("/hello")
public String hello(String name){
   System.out.println(name);
   return "hello";
}

2、提交的域名稱和處理方法的引數名不一致

提交資料 : http://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、提交資料 : http://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框架的整合

 



相關文章