日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring MVC-03循序渐进之Spring MVC

發(fā)布時間:2025/3/21 javascript 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC-03循序渐进之Spring MVC 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

概述

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


Spring MVC體系概述

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

  • 根據(jù)URI調(diào)用對應(yīng)的action
  • 實例化正確的控制器類
  • 根據(jù)請求參數(shù)來構(gòu)造表單bean
  • 調(diào)用控制器對象的相應(yīng)方法
  • 轉(zhuǎn)向一個視圖
  • Spring MVC框架圍繞DispatcherServlet這個核心展開,DispatcherServlet負(fù)責(zé)截獲請求并分派給相應(yīng)的處理器處理。 SpringMVC框架包括注解驅(qū)動控制器、請求及響應(yīng)的信息處理、視圖解析、本地化解析、上傳文件解析、異常處理及表單標(biāo)簽綁定等內(nèi)容。


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

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

    下面我們來分步解析下SpringMVC處理請求的整體過程

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

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

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

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

  • ModelAndView并非真正的視圖對象,DispatcherServlet通過ViewResolver完成邏輯視圖和真實視圖對象的解析工作

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

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


  • Spring MVC的DispatcherServlet

    我們在前面兩篇博文的例子中,servlet需要我們自己編寫,基于Spring MVC ,則無需如此。 SpringMVC中自帶了一個開箱即用的DispatcherServlet,全限定名為org.springframework.web.servlet.DispatcherServlet

    使用DispatcherServlet

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

    <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><!-- map all requests to DispatcherServlet --><url-pattern>/</url-pattern></servlet-mapping> </web-app>
    • servlet元素內(nèi)的on-startup是可選項,如果它存在,則它將在應(yīng)用程序啟動時裝載servlet并調(diào)用他的init方法,若不存在,則該servlet的第一個請求時加載

    • DispatcherServlet將使用Spring MVC諸多默認(rèn)的組件,此外,初始化的時候,它會尋找一個在應(yīng)用程序的WEB-INF目錄下的配置文件,該配置文件的命名規(guī)則 servletName-servlet.xml 。 其中servletName是在部署描述中的DispatcherServlet的名稱,比如我們上述的配置文件 <servlet-name>springmvc</servlet-name>,則在WEB-INF下對應(yīng)的文件為springmvc-servlet.xml.

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

    <servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/config/simple-config.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet>

    Controller接口

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

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

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

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


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

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

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

    pom.xml添加依賴

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.artisan</groupId><artifactId>chapter03a</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>chapter03a Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope><!-- provided 依賴只有在當(dāng)JDK 或者一個容器已提供該依賴之后才使用。 例如, 如果你開發(fā)了一個web 應(yīng)用,你可能在編譯 classpath 中需要可用的Servlet API 來編譯一個servlet,但是你不會想要在打包好的WAR 中包含這個Servlet API;這個Servlet API JAR 由你的應(yīng)用服務(wù)器或者servlet 容器提供。已提供范圍的依賴在編譯classpath (不是運行時)可用。它們不是傳遞性的,也不會被打包。 --></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.3.9.RELEASE</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies><build><finalName>chapter03a</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.5.1</version><configuration><source>1.7</source><target>1.7</target><compilerArgument>-Xlint:all</compilerArgument><showWarnings>true</showWarnings><showDeprecation>true</showDeprecation></configuration></plugin></plugins></build> </project>

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

    部署描述文件web.xml

    <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- load servlet file by contextConfigLocation --><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/config/artisan-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><!-- map *.action requests to DispatcherServlet --><url-pattern>*.action</url-pattern></servlet-mapping> </web-app>

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

    Spring MVC配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean name="/product_input.action" class="com.artisan.springmvc.controller.InputProductController"/><bean name="/product_save.action" class="com.artisan.springmvc.controller.SaveProductController"/></beans>

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


    Controller

    下面來編寫“傳統(tǒng)”風(fēng)格的控制器,分別實現(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 實現(xiàn)Spring自身的Controller**/ public class InputProductController implements Controller{private static final Logger logger = Logger.getLogger(InputProductController.class);@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {logger.info("InputProductController called");return new ModelAndView("/WEB-INF/jsp/ProductForm.jsp");}}

    InputProductController 類的handleRequest方法只返回一個ModelAndView對象,包含一個視圖,并沒有模型。因此,該請求將被轉(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 實現(xiàn)Spring自身的Controller**/ public class SaveProductController implements Controller{private static final Logger logger = Logger.getLogger(SaveProductController.class);@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {logger.info("SaveProductController called");ProductForm productForm = new ProductForm();// populate action propertiesproductForm.setName(request.getParameter("name"));productForm.setDescription(request.getParameter("description"));productForm.setPrice(request.getParameter("price"));// create modelProduct 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 Productreturn new ModelAndView("/WEB-INF/jsp/ProductDetails.jsp", "product",product);}}

    SaveProductController類的handleRequest方法中,首先用請求創(chuàng)建了一個ProductForm對象,然后它根據(jù)ProductForm對象創(chuàng)建Product對象 。 由于ProductForm的price是一個字符串,而在Product類中是一個float類型,因此需要轉(zhuǎn)型(后面會介紹通過數(shù)據(jù)綁定省去ProductForm,這里暫不講解)

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


    視圖

    兩個JSP,綁定了CSS樣式。
    我們在web.xml配置url-pattern來匹配.action ,沒有配置 / (所有請求)是因為如果配置了/,而沒有配置靜態(tài)資源過濾,這個CSS也會被攔截,因此這里暫時配置了攔截所有action結(jié)尾的請求。

    ProductForm.jsp

    <!DOCTYPE HTML> <html> <head> <title>Add Product Form</title> <style type="text/css">@import url(css/main.css);</style> </head> <body><div id="global"><form action="product_save.action" method="post"><fieldset><legend>Add a product</legend><p><label for="name">Product Name: </label><input type="text" id="name" name="name" tabindex="1"></p><p><label for="description">Description: </label><input type="text" id="description" name="description" tabindex="2"></p><p><label for="price">Price: </label><input type="text" id="price" name="price" tabindex="3"></p><p id="buttons"><input id="reset" type="reset" tabindex="4"><input id="submit" type="submit" tabindex="5" value="Add Product"></p></fieldset> </form> </div> </body> </html>

    ProductDetails.jsp

    <!DOCTYPE HTML> <html> <head> <title>Save Product</title> <style type="text/css">@import url(css/main.css);</style> </head> <body> <div id="global"><h4>The product has been saved.</h4><p><h5>Details:</h5>Product Name: ${product.name}<br/>Description: ${product.description}<br/>Price: ${product.price}</p> </div> </body> </html>

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


    測試應(yīng)用

    輸入URL:
    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

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

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

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

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

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean>

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

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

    InputProductController 修改為

    return new ModelAndView("ProductForm");

    SaveProductController修改為

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

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


    總結(jié)

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


    源碼

    代碼已提交到github

    https://github.com/yangshangwei/SpringMvcTutorialArtisan

    總結(jié)

    以上是生活随笔為你收集整理的Spring MVC-03循序渐进之Spring MVC的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。