Spring MVC-03循序漸進(jìn)Spring MVC(spring boot)

      網(wǎng)友投稿 827 2025-04-01

      概述


      前面兩篇介紹了模型2架構(gòu)的優(yōu)勢(shì)以及如何構(gòu)建一個(gè)模型2應(yīng)用。但是Spring MVC框架可以幫助我們快速的開發(fā)MVC應(yīng)用。

      Spring MVC體系概述

      若基于某個(gè)框架來開發(fā)一個(gè)模型2的應(yīng)用程序,我們要負(fù)責(zé)編寫一個(gè)Dispatcher servlet和控制類。 其中Dispatcher servlet必須能夠做到如下事情:

      根據(jù)URI調(diào)用對(duì)應(yīng)的action

      實(shí)例化正確的控制器類

      根據(jù)請(qǐng)求參數(shù)來構(gòu)造表單bean

      調(diào)用控制器對(duì)象的相應(yīng)方法

      轉(zhuǎn)向一個(gè)視圖

      Spring MVC框架圍繞DispatcherServlet這個(gè)核心展開,DispatcherServlet負(fù)責(zé)截獲請(qǐng)求并分派給相應(yīng)的處理器處理。 SpringMVC框架包括注解驅(qū)動(dòng)控制器、請(qǐng)求及響應(yīng)的信息處理、視圖解析、本地化解析、上傳文件解析、異常處理及表單標(biāo)簽綁定等內(nèi)容。

      由于SpringMVC是基于Model2實(shí)現(xiàn)的框架,所以它底層的機(jī)制也是MVC,我們來看下SpringMVC的整體架構(gòu)

      從接收請(qǐng)求到返回相應(yīng),Spring MVC框架的眾多組件有條不紊的完成內(nèi)部的分工,在整個(gè)框架中,DispatcherServlet處于核心的位置,負(fù)責(zé)協(xié)調(diào)和組織不同組件以完成請(qǐng)求處理并返回響應(yīng)的工作。

      下面我們來分步解析下SpringMVC處理請(qǐng)求的整體過程

      整個(gè)過程始于客戶端發(fā)出的一個(gè)HTTP請(qǐng)求,Web應(yīng)用服務(wù)器收到這個(gè)請(qǐng)求后,如果匹配DispatcherServlet的請(qǐng)求映射路徑(web.xml中指定),則web容器將該請(qǐng)求交給DispatcherServlet處理

      DispatcherServlet接收到這請(qǐng)求后,將根據(jù)請(qǐng)求的信息(包括url,HTTP方法、請(qǐng)求報(bào)文頭、請(qǐng)求參數(shù)、Cookie等)及HandlerMapping的配置找到處理請(qǐng)求的處理器(Handler)。 可將HandlerMapping看做是路由控制器,將Handler看做目標(biāo)主機(jī)。值得注意的是,SpringMVC中并沒有定義一個(gè)Handler接口,實(shí)際上任何一個(gè)Object都可以稱為請(qǐng)求處理器。

      當(dāng)DispatcherServlet根據(jù)HandlerMapping得到對(duì)應(yīng)請(qǐng)求的Handler后,通過HandlerAdpapter對(duì)Handler進(jìn)行封裝再以統(tǒng)一的適配器接口調(diào)用Handler.

      處理器完成業(yè)務(wù)邏輯的處理后將返回一個(gè)ModelAndView給DispatcherServlet,ModelAndView包含了視圖邏輯名和模型數(shù)據(jù)信息

      ModelAndView并非真正的視圖對(duì)象,DispatcherServlet通過ViewResolver完成邏輯視圖和真實(shí)視圖對(duì)象的解析工作

      當(dāng)?shù)玫秸鎸?shí)的視圖對(duì)象View后,DispatcherServlet就使用這個(gè)View對(duì)ModelAndView中的模型數(shù)據(jù)進(jìn)行視圖渲染

      最終客戶端得到相應(yīng)消息可能是一個(gè)普通的html頁面,也可能是要給XML或者JSON串,甚至是一張圖片或者PDF文檔等不同的媒體形式。

      Spring MVC的DispatcherServlet

      我們?cè)谇懊鎯善┪牡睦又校瑂ervlet需要我們自己編寫,基于Spring MVC ,則無需如此。

      SpringMVC中自帶了一個(gè)開箱即用的DispatcherServlet,全限定名為org.springframework.web.servlet.DispatcherServlet

      使用DispatcherServlet

      要想使用這個(gè)servlet,同樣的也需要把它配置在部署描述符(web.xml)、應(yīng)用servlet和servlet-mapping。如下所示

      springmvc org.springframework.web.servlet.DispatcherServlet 1 springmvc /

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      servlet元素內(nèi)的on-startup是可選項(xiàng),

      如果它存在,則它將在應(yīng)用程序啟動(dòng)時(shí)裝載servlet并調(diào)用他的init方法,若不存在,則該servlet的第一個(gè)請(qǐng)求時(shí)加載

      DispatcherServlet將使用Spring MVC諸多默認(rèn)的組件,此外,

      初始化的時(shí)候,它會(huì)尋找一個(gè)在應(yīng)用程序的WEB-INF目錄下的配置文件,該配置文件的命名規(guī)則 servletName-servlet.xml

      。 其中servletName是在部署描述中的DispatcherServlet的名稱,比如我們上述的配置文件 springmvc,則在WEB-INF下對(duì)應(yīng)的文件為springmvc-servlet.xml.

      此外,也可以把SpringMVC的配置文件放在應(yīng)用程序目錄中的任何地方,用servlet定義的init-param元素,以便DispatcherServlet加載到該文件。 init-param元素?fù)碛幸粋€(gè)contextConfigLocation的param-name元素,其param-value元素則包含配置文件的路徑。

      如下所示

      springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation /WEB-INF/config/simple-config.xml 1

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      Controller接口

      Spring2.5之前

      ,開發(fā)一個(gè)控制器的唯一方法是實(shí)現(xiàn)org.springframework.web.servlet.mvc.Controller接口,該接口中有一個(gè)方法

      ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

      1

      其實(shí)現(xiàn)類可以訪問對(duì)應(yīng)請(qǐng)求的HttpServletRequest 和HttpServletResponse ,同時(shí)還必須返回包含視圖路徑或者視圖路徑和模的ModelAndView 對(duì)象。

      Controller接口實(shí)現(xiàn)類只能處理一個(gè)單一動(dòng)作,而一個(gè)基于注解的控制器可以同時(shí)支持多個(gè)請(qǐng)求處理動(dòng)作,并且無需實(shí)現(xiàn)任何接口(后續(xù)介紹這種主流的開發(fā)方式,這里先演示下實(shí)現(xiàn)接口的方式)

      簡單示例(實(shí)現(xiàn)接口的方式)

      在這里我們只是簡單的演示一下這種方式的用法,實(shí)際開發(fā)中并不推薦這樣做。基于注解的方式后續(xù)介紹。

      maven工程結(jié)構(gòu)如下:

      pom.xml添加依賴

      4.0.0 com.artisan chapter03a war 0.0.1-SNAPSHOT chapter03a Maven Webapp http://maven.apache.org junit junit 3.8.1 test javax.servlet javax.servlet-api 3.1.0 provided org.springframework spring-webmvc 4.3.9.RELEASE log4j log4j 1.2.17 chapter03a org.apache.maven.plugins maven-compiler-plugin 2.5.1 1.7 1.7 -Xlint:all true true

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      部署描述文件和Spring MVC 的配置文件

      部署描述文件web.xml

      springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation /WEB-INF/config/artisan-servlet.xml 1 springmvc *.action

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      這里告訴Servlet/JSP容器,我們將使用SpringMVC的DispatcherServlet,并通過配置url-pattern原始來匹配.action結(jié)尾的URL映射到該servlet。 并通過init-param元素,加載特定目錄下的Spring MVC 配置文件人,如果不配置的話,則SpringMVC的配置文件將在默認(rèn)的/WEB-INF目錄下,并且按照約定的命名規(guī)范。

      Spring MVC配置文件

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      這里聲明兩個(gè)控制器類InputProductController和SaveProductController,并分別映射到/product_input.action和/product_save.action。

      Controller

      下面來編寫“傳統(tǒng)”風(fēng)格的控制器,分別實(shí)現(xiàn)Spring提供的Controller接口

      package com.artisan.springmvc.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; /** * * @author Mr.Yang * @Desc 實(shí)現(xiàn)Spring自身的Controller * */ public class InputProductController implements Controller{ private static final Logger logger = Logger.getLogger(InputProductController.class); @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { logger.info("InputProductController called"); return new ModelAndView("/WEB-INF/jsp/ProductForm.jsp"); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      InputProductController 類的handleRequest方法只返回一個(gè)ModelAndView對(duì)象,包含一個(gè)視圖,并沒有模型。因此,該請(qǐng)求將被轉(zhuǎn)發(fā)到/WEB-INF/jsp/ProductForm.jsp頁面

      package com.artisan.springmvc.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import com.artisan.springmvc.form.ProductForm; import com.artisan.springmvc.model.Product; /** * * @author Mr.Yang * @Desc 實(shí)現(xiàn)Spring自身的Controller * */ public class SaveProductController implements Controller{ private static final Logger logger = Logger.getLogger(SaveProductController.class); @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { logger.info("SaveProductController called"); ProductForm productForm = new ProductForm(); // populate action properties productForm.setName(request.getParameter("name")); productForm.setDescription(request.getParameter("description")); productForm.setPrice(request.getParameter("price")); // create model Product product = new Product(); product.setName(productForm.getName()); product.setDescription(productForm.getDescription()); try { product.setPrice(Float.parseFloat(productForm.getPrice())); } catch (NumberFormatException e) { } // insert code to save Product return new ModelAndView("/WEB-INF/jsp/ProductDetails.jsp", "product", product); } }

      Spring MVC-03循序漸進(jìn)之Spring MVC(spring boot)

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      SaveProductController類的handleRequest方法中,首先用請(qǐng)求創(chuàng)建了一個(gè)ProductForm對(duì)象,然后它根據(jù)ProductForm對(duì)象創(chuàng)建Product對(duì)象 。 由于ProductForm的price是一個(gè)字符串,而在Product類中是一個(gè)float類型,因此需要轉(zhuǎn)型(

      后面會(huì)介紹通過數(shù)據(jù)綁定省去ProductForm,這里暫不講解)

      SaveProductController的handleRequest方法返回最后的ModelAndView模型包含了視圖的路徑、模型名稱和模型(Product對(duì)象),該模型將提供給目標(biāo)視圖,用于界面顯示。

      視圖

      兩個(gè)JSP,綁定了CSS樣式。

      我們?cè)趙eb.xml配置url-pattern來匹配.action ,沒有配置 / (所有請(qǐng)求)是因?yàn)槿绻渲昧?,而沒有配置靜態(tài)資源過濾,這個(gè)CSS也會(huì)被攔截,因此這里暫時(shí)配置了攔截所有action結(jié)尾的請(qǐng)求。

      ProductForm.jsp

      Add Product Form

      Add a product

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      ProductDetails.jsp

      Save Product

      The product has been saved.

      Details:
      Product Name: ${product.name}
      Description: ${product.description}
      Price: ${product.price}

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      ProductDetail.jsp頁面通過模型屬性名“product”來訪問由SaveProductController傳入的Product對(duì)象。這里用JSP表達(dá)式來顯示Product對(duì)象的各種屬性,后續(xù)會(huì)詳解JSP 的EL表達(dá)式。

      測試應(yīng)用

      輸入U(xiǎn)RL:

      http://localhost:8080/chapter03a/product_input.action

      輸入相應(yīng)的數(shù)據(jù)

      提交數(shù)據(jù)后,url跳轉(zhuǎn)到

      http://localhost:8080/chapter03a/product_save.action

      View Resolver

      上個(gè)案例中,頁面的跳轉(zhuǎn)通過指定頁面的路徑來完成的,比如

      new ModelAndView("/WEB-INF/jsp/ProductDetails.jsp", "product", product);

      1

      2

      其實(shí),Spring MVC為我們提供了視圖解析器,負(fù)責(zé)解析視圖,現(xiàn)在我們來改造下。

      在SpringMVC的配置文件中配置視圖解析器

      1

      2

      3

      4

      如上視圖解析器前綴和后綴兩個(gè)屬性,這樣一來,view的路徑就縮短了。 比如僅需要ProductDetails,而無需設(shè)置/WEB-INF/jsp/ProductDetails.jsp,視圖解析器就會(huì)自動(dòng)增加前綴和后綴。

      緊接著我們調(diào)整下控制器中的頁面跳轉(zhuǎn)

      InputProductController 修改為

      return new ModelAndView("ProductForm");

      1

      SaveProductController修改為

      return new ModelAndView("ProductDetails", "product", product);

      1

      2

      重新運(yùn)行測試,結(jié)果同上。

      總結(jié)

      本博文是Spring MVC的入門介紹,我們知道了使用SpringMVC,我們無需編寫自己的DispatcherServlet,其傳統(tǒng)風(fēng)格的控制器開發(fā)方式是實(shí)現(xiàn)控制器接口。 從Spring2.5版本開始,Spring提供了基于注解的方式開發(fā)控制器,下篇博文介紹。

      源碼

      代碼已提交到github

      https://github.com/yangshangwei/SpringMvcTutorialArtisan

      MVC Servlet Spring

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:C++ Primer Plus 第4章 復(fù)合類型 學(xué)習(xí)筆記
      下一篇:互聯(lián)網(wǎng) 生產(chǎn)制造(互聯(lián)網(wǎng)生產(chǎn)制造業(yè))
      相關(guān)文章
      亚洲?v女人的天堂在线观看| 亚洲乱妇熟女爽到高潮的片| 亚洲国产欧美一区二区三区| 亚洲国产精品久久丫| 亚洲AV无码AV男人的天堂| 精品亚洲综合在线第一区| 亚洲三区在线观看无套内射| 亚洲日韩精品无码专区网址| 亚洲中文字幕成人在线| 亚洲午夜成人精品电影在线观看| 亚洲精品无码久久久久AV麻豆| 亚洲日韩在线第一页| 久久激情亚洲精品无码?V| 国产综合精品久久亚洲| 伊人久久大香线蕉亚洲| 亚洲国产一二三精品无码| 亚洲欧洲自拍拍偷午夜色无码| 亚洲性猛交XXXX| 亚洲AV无码一区东京热久久| 亚洲av福利无码无一区二区| 91久久亚洲国产成人精品性色| 亚洲精品在线网站| 久久亚洲国产成人影院| 国产精品国产亚洲区艳妇糸列短篇| 韩国亚洲伊人久久综合影院| 亚洲欧洲精品成人久久曰影片| 日韩亚洲变态另类中文| 亚洲成在人线av| 亚洲黄色中文字幕| 国产精品高清视亚洲一区二区| 亚洲精品人成网线在线播放va| 亚洲a∨国产av综合av下载| 亚洲成a人片在线观看久| 亚洲综合伊人久久综合| 久久精品国产精品亚洲蜜月| 亚洲美女中文字幕| 久久亚洲精品国产亚洲老地址| 国产区图片区小说区亚洲区| 国产自偷亚洲精品页65页| 亚洲国产老鸭窝一区二区三区| 亚洲成AV人综合在线观看|