springMvc01

spring01


  1. 概述
    • springMvc是一種基於Java實現MVC設計模式的請求驅動類型的輕量級web框架
    • 它經過一套註解, 讓一個簡單的Java類成爲處理請求的控制器, 而無需實現任何接口
    • 支持REST編程風格
    • 它在MVC三層架構中處於表現層
  2. springMvc和struts2優劣分析
    1. 共同點:
      • 它們都是表現層框架,都是基於 MVC 模型編寫的。
      • 它們的底層都離不開原始 ServletAPI。
      • 它們處理請求的機制都是一個核心控制器。
    2. 區別:
      • Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter
      • Spring MVC 是基於方法設計的,而 Struts2 是基於類,Struts2 每次執行都會建立一個動做類。因此 Spring MVC 會稍微比 Struts2 快些。
      • Spring MVC 使用更加簡潔,同時還支持 JSR303, 處理 ajax 的請求更方便
        • JSR303 是一套 JavaBean 參數校驗的標準,它定義了不少經常使用的校驗註解,咱們能夠直接將這些註解加在咱們 JavaBean 的屬性上面,就能夠在須要校驗的時候進行校驗了。
      • Struts2 的 OGNL 表達式使頁面的開發效率相比 Spring MVC 更高些,但執行效率並無比 JSTL 提高,尤爲是 struts2 的表單標籤,遠沒有 html 執行效率高。
  3. springMvc基本執行流程
    • 執行流程
  4. hello
    1. 搭建環境
      1. 導依賴html

        <dependencies>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
          </dependency>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.0.2.RELEASE</version>
          </dependency>
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.2.RELEASE</version>
          </dependency>
          <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
          </dependency>
          <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
          </dependency>
        </dependencies>
      2. 寫springMvc配置文件前端

        <?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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
            <!-- 開啓註解掃描 -->
            <context:component-scan base-package="cn.ann"/>
        
            <!-- 配置視圖解析器 -->
            <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value=""/>
                <property name="suffix" value=".html"/>
            </bean>
        
            <!-- 開啓springMvc註解支持 -->
            <mvc:annotation-driven/>
        
            <!-- 靜態資源放行 -->
            <mvc:default-servlet-handler/>
        </beans>
      3. web.xmljava

        <?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">
            <servlet>
                <!-- 配置springMvc -->
                <servlet-name>dispatcherServlet</servlet-name>
                <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                <init-param>
                    <param-name>contextConfigLocation</param-name>
                    <param-value>classpath:springMvc.xml</param-value>
                </init-param>
                <!-- 配置加載時機 -->
                <load-on-startup>1</load-on-startup>
            </servlet>
            <servlet-mapping>
                <servlet-name>dispatcherServlet</servlet-name>
                <url-pattern>/</url-pattern>
            </servlet-mapping>
        </web-app>
    2. 編寫程序
      • 編寫Controller類git

        @Controller
        public class HelloController {
            @RequestMapping("/hello")
            public String hello() {
                System.out.println("hello springMvc");
                return "success";
            }
        }
      • 寫頁面, 加一個a標籤便可, href爲hello
    3. 啓動服務器, 加載配置文件
      • DispatcherServlet對象建立
      • springMvc.xml加載
      • HelloController對象建立
    4. 發送請求, 後臺處理請求
      • hello1
      • hello2
      • hello3
  5. springMvc框架結構
    springMvc組件圖
    • 執行流程
      1. 用戶發送請求到前端控制器 DispatcherServlet
      2. DispatcherServlet收到請求調用HandlerMapping處理器映射器
      3. 處理器映射器根據請求url找到具體的處理器, 生成處理器對象及處理器攔截器(若是有則生成)一併返回給DispatcherServlet
      4. DispatcherServlet經過HandlerAdapter處理器適配器調用處理器
      5. 執行處理器/後端控制器Controller
      6. Controller執行完成返回ModelAndView
      7. HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet
      8. DispatcherServlet將ModelAndView傳給ViewResolver視圖解析器
      9. ViewResolver解析後返回具體View
      10. DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)
      11. DispatcherServlet響應用戶
    • 組件說明
      1. DispatcherServlet:前端控制器
        • 用戶請求到達前端控制器, 它就至關於mvc模式中的c, dispatcherServlet是整個流程控制的中心, 由它調用其它組件處理用戶的請求, dispatcherServlet的存在下降了組件之間的耦合性
      2. HandlerMapping:處理器映射器
        • HandlerMapping負責根據用戶請求url找到Handler即處理器, springMvc提供了不一樣的映射器實現不一樣的映射方式, 例如: 配置文件方式, 實現接口方式, 註解方式等
      3. Handler:處理器
        • Handler是繼DispatcherServlet前端控制器的後端控制器, 在DispatcherServlet的控制下Handler對具體的用戶請求進行處理
        • 因爲Handler涉及到具體的用戶業務請求, 因此通常狀況須要程序員根據業務需求開發Handler
      4. HandleAdapter:處理器適配器
        • 經過HandlerAdapter對處理器進行執行, 這是適配器模式的應用, 經過擴展適配器能夠對更多類型的處理器進行執行
        • Java的io流中就運用了適配器模式(轉換流)
      5. ViewResolver:視圖解析器
        • ViewResolver負責將處理結果生成View視圖, ViewResolver首先根據邏輯視圖名解析成物理視圖名即具體的頁面地址, 再生成View視圖對象, 最後對View進行渲染, 將處理結果經過頁面展現給用戶
      6. View:視圖
        • springMvc框架提供了不少的View視圖類型的支持, 包括: jsPlView, freemarkerView, pdfView等. 咱們最經常使用的視圖就是jsp
        • 通常狀況下須要經過頁面標籤或頁面模版技術將模型數據經過頁面展現給用戶, 須要由程序員根據業務需求開發具體的頁面
      • springMvc.xml中<mvc:annotation-driven/>的做用: 配置這個標籤就至關於配置了處理器映射器(HandleMapping), 處理器適配器(HandleAdapter) 和 異常解析器(ExceptionResolver)
      • 在springMvc的各個組件中, 處理器映射器 & 處理器適配器 & 視圖解析器稱爲springMvc的三大組件. 須要用戶開發的組件有handler & view
  6. @RequestMapping解析:
    1. 位置: 能夠做用在類上或方法上(便於分模塊開發)
    2. 屬性:
      • value(path): 兩個屬性做用同樣, 用於指定映射路徑, 須要以 '/' 開頭
      • method: 用於指定容許接受的請求方式
      • params: 用於指定限制請求參數的條件. 支持簡單的表達式, 可是要求請求參數的key和value必須和配置的如出一轍
        • {"name"}: 參數名必須是name
        • {"age>10"}: age不能是10
      • headers: 指定必須有的請求頭
    3. 擴展(瞭解): path屬性支持Ant風格的url
      • ant風格:
        • ?: 匹配文件名的一個字符.
          • /springMvc01/anno/??/testAntPath ====> /springMvc01/anno/12/testAntPath
          • /springMvc01/anno/??testAntPath ====> /springMvc01/anno/12testAntPath
        • *: 匹配文件名的任意(多個)字符.
          • /springMvc01/anno/*/testAntPath ====> /springMvc01/anno/12asdfasd啊啊啊/testAntPath
          • /springMvc01/anno/*testAntPath ====> /springMvc01/anno/12asdfasd啊啊啊testAntPath
        • **: 匹配多層路徑.
          • /springMvc01/anno/**/testRequestHeader ====> /springMvc01/anno/12/a/sd/fa/sd/啊/啊啊/testAntPath
          • /springMvc01/anno/**testRequestHeader ====> 這種寫法是錯誤的
        • ant風格的一個坑:
          • 在向 requestMapping 中添加ant風格的url時, '?', '*'須要放在'/'後面, '**' 必須包裹在兩個'/'中間
  7. 參數綁定: 方法的參數列表裏面的參數
    1. 基本類型和String等
      • post表單提交的name和參數名一致便可
    2. 亂碼問題: 添加過濾器便可程序員

      <filter>
          <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
    3. 對象屬性: 要求提供getter和setter
      • 基本屬性和String: post表單提交的name和屬性名一致便可
      • 對象: 如User中有Address類型的屬性addr, Address中有屬性name. 寫addr.name便可
    4. 對象中的list和map類型
      • list: list的屬性名[索引值].屬性 ---> 屬性指的是list泛型的屬性
      • map: map的屬性名['key'].屬性 ---> 屬性指的是map第二個泛型的屬性
    5. 自定義類型轉換器
      1. 編寫自定義的轉換器github

        public class StringToDateConverter implements Converter<String, Date> {
            @Override
            public Date convert(String s) {
                try {
                    if (Pattern.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$", s)) {
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                        return format.parse(s);
                    } else if (Pattern.matches("^\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$", s)) {
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        return format.parse(s);
                    } else if (Pattern.matches("^\\d{4}-\\d{1,2}-\\d{1,2}[T]\\d{1,2}:\\d{1,2}:\\d{1,2}$", s)) {
                        s = s.replace('T', ' ');
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        return format.parse(s);
                    } else {
                        throw new RuntimeException("輸入格式不正確");
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        }
      2. 註冊到spring中web

        <!-- 註冊自定義轉換器 -->
        <bean id="conversionServiceFactory" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <set>
                    <bean class="cn.ann.utils.StringToDateConverter"/>
                </set>
            </property>
        </bean>
        
        <!-- 開啓springMvc註解支持 -->
        <mvc:annotation-driven conversion-service="conversionServiceFactory"/>
    6. 獲取原生的request和response(原生的ServletAPI對象): 在參數列表添加參數便可
  8. 經常使用註解: 若沒有特殊說明, 如下注釋全是用於參數列表中的參數的
    1. @RequestParam: 解決參數列表中參數名和post表單中name值不一致的問題
      • 屬性:
        • name(value): 請求參數中的名稱
        • required: 請求參數中是否必須提供此參數, 默認爲true
        • defaultValue: 設置默認值
    2. @RequestBody(經常使用於異步(ajax)請求中): 用於獲取請求體的內容, 直接使用獲取到的是key=value&key=value的數據
      • 屬性:
        • required: 是否必須有請求體. 默認值是true.
          • 值爲true時, get請求方式會報錯
          • 值爲false時, get請求會返回null
      • 不適用於get方式, 由於get方式沒有請求體
    3. @PathVariable: 用於綁定url中的佔位符. 例如: 請求url中 /delete/{id}, 這個{id}就是url佔位符. url支持佔位符是spring3.0以後加入的. 是springMvc支持rest風格URL的一個重要標誌
      • 屬性:
        1. name(value): 用於指定url中佔位符名稱
        2. required: 是否必須提供佔位符
      • rest風格:ajax

        什麼是rest:
           REST(英文:Representational State Transfer,簡稱REST)描述了一個架構樣式的網絡系統,好比 web 應用程序。它首次出如今 2000 年 Roy Fielding 的博士論文中,他是 HTTP 規範的主要編寫者之一。在目前主流的三種Web服務交互方案中,REST相比於SOAP(Simple Object Access protocol,簡單對象訪問協議)以及XML-RPC更加簡單明瞭,不管是對URL的處理仍是對Payload的編碼,REST都傾向於用更加簡單輕量的方法設計和實現。值得注意的是REST並無一個明確的標準,而更像是一種設計的風格。 
           它自己並無什麼實用性,其核心價值在於如何設計出符合REST風格的網絡接口。 
        restful的優勢 
           它結構清晰、符合標準、易於理解、擴展方便,因此正獲得愈來愈多網站的採用。 
        restful的特性: 
           資源(Resources):網絡上的一個實體,或者說是網絡上的一個具體信息。 它能夠是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的存在。能夠用一個URI(統一資源定位符)指向它,每種資源對應一個特定的 URI 。要 獲取這個資源,訪問它的URI就能夠,所以 URI 即爲每個資源的獨一無二的識別符。 
           表現層(Representation):把資源具體呈現出來的形式,叫作它的表現層 (Representation)。 好比,文本能夠用 txt 格式表現,也能夠用 HTML 格式、XML 格式、JSON 格式表現,甚至能夠採用二進制格式。 
           狀態轉化(State Transfer):每 發出一個請求,就表明了客戶端和服務器的一次交互過程。 HTTP協議,是一個無狀態協議,即全部的狀態都保存在服務器端。所以,若是客戶端想要操做服務器,必須經過某種手段,讓服務器端發生「狀態轉化」(State Transfer)。而這種轉化是創建在表現層之上的,因此就是 「表現層狀態轉化」。具體說,就是 HTTP 協議裏面,四個表示操做方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操做:GET 用來獲取資源,POST 用來新建資源,PUT 用來更新資源,DELETE 用來刪除資源。
        • restful的示例:
          • /account/1 HTTP GET : 獲得 id = 1 的 account
          • /account/1 HTTP DELETE: 刪除 id = 1的 account
          • /account/1 HTTP PUT: 更新id = 1的 account
          • /account HTTP POST: 新增 account
      • 瀏覽器form表單僅支持get和post, 因此spring添加了一個過濾器, 能夠將這些請求轉化爲標準的http方法, 從而支持GET, POST, PUT 和 DELETE
        • HiddenHttpMethodFilter
        • 須要在form表單中添加hidden表單項:
          • <input type="hidden" name="_method" value="GET|POST|PUT|DELETE"/>
    4. @RequestHeader: 用於獲取請求消息頭
      • 屬性:
        1. name(value): 提供消息頭名稱
        2. required: 是否必須有此消息頭
      • 在實際開發中並不經常使用
    5. @CookieValue: 用於把指定cookie名稱的值傳入控制器方法參數
      • 屬性:
        1. name(value): 指定cookie的名稱
        2. required: 是否必須有此cookie
    6. @ModelAttribute: 該註解是SpringMVC4.3版本之後新加入的。它能夠用於修飾方法和參數
      • 位置:
        1. 出如今方法上, 表示當前方法會在控制器的方法執行以前, 先執行. 它能夠修飾沒有返回值的方法, 也能夠修飾有具體返回值的方法
        2. 出如今參數上,獲取指定的數據給參數賦值
      • 屬性:
        1. name(value): 用於獲取數據的key. key能夠是POJO的屬性名稱, 也能夠是map結構的key
        2. binding: 表示是否必須綁定數據. 默認是true
      • 應用場景:
        • 當表單提交數據不是完整的實體類數據時, 保證沒有提交數據的字段使用數據庫對象原來的數據
      • 示例代碼spring

        @RequestMapping("/testModelAttribute")
        public String testModelAttribute(@ModelAttribute("user01") User user) {
            System.out.println("testModelAttribute run...");
            System.out.println(user);
            return "success";
        }
        
        /**
         * 多用於填充對象的空數據, 能夠在使用對象以前將對象的全部信息從數據庫中查出來
         */
        @ModelAttribute
        public void model(User user, Map<String, User> map) {
            System.out.println("model run..."+user);
            // 能夠在這裏面寫從數據庫查詢的操做
            user.setBirthday(new Date());
            map.put("user01", user);
        }
    7. @SessionAttributes: 用於屢次執行控制器方法間的參數共享
      • 位置: 類上
        • @SessionAttributes(value = "user", types = User.class)
      • 屬性:
        1. names(value): 用於指定存入的屬性名稱, 數組類型
        2. type: 用於指定存入的數據類型, 數組類型
      @RequestMapping("/testSessionAttributesPut")
      public String testSessionAttributesPut(Model model) {
          User user = new User();
          user.setName("sessionZS");
          user.setAge(23);
          user.setBirthday(new Date());
          model.addAttribute(user);
          return "success";
      }
      
      @RequestMapping("/testSessionAttributesGet")
      public String testSessionAttributesGet(ModelMap model) {
          System.out.println(model.get("user"));
          return "success";
      }
      
      @RequestMapping("/testSessionAttributesClean")
      public String testSessionAttributesClean(SessionStatus status) {
          status.setComplete();
          return "success";
      }
    8. @InitBinder: 由該註解標識的方法, 能夠完成對WebDataBinder對象的初始化. WebDataBinder是DataBinder的子類, 用於完成表單字段到JavaBean屬性的綁定. 簡單地說, 就是能夠設置哪些表單屬性不用映射到JavaBean
      • @InitBinder標識的方法不能有返回值, 必須聲明爲void
      • @InitBinder方法的參數通常是WebDataBinder

本文代碼: 此處的 springMvc01數據庫

相關文章
相關標籤/搜索