




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
JavaWeb編程技術(shù)本章首先介紹SpringMVC的處理流程,然后介紹控制器和請(qǐng)求處理方法的編寫(xiě),最后介紹請(qǐng)求參數(shù)以及幾個(gè)常用注解的使用。SpringMVC體系結(jié)構(gòu)控制器與請(qǐng)求處理方法請(qǐng)求參數(shù)接收的方式常用注解的使用第10章SpringMVC入門(mén)SpringMVC是Web應(yīng)用的表示層提供的一個(gè)優(yōu)秀MVC框架。與其他眾多的Web框架一樣,SpringMVC基于MVC設(shè)計(jì)理念,采用了松散耦合、可插拔的組件結(jié)構(gòu),比其他MVC框架更具有可擴(kuò)展性和靈活性。SpringMVC體系結(jié)構(gòu)SpringMVC是基于模型2實(shí)現(xiàn)的技術(shù)框架,模型2是經(jīng)典的MVC模型,利用處理器分離模型、視圖和控制,以便達(dá)到不同層之間松散耦合的效果,提供系統(tǒng)的可重用性、維護(hù)性和靈活性。SpringMVC不需要實(shí)現(xiàn)任何接口,它通過(guò)一套MVC注解讓POJO成為處理請(qǐng)求的控制器,且在數(shù)據(jù)綁定、視圖解析、本地化處理及靜態(tài)資源處理上都有許多不俗的表現(xiàn)。10.1.1SpringMVC處理流程10.1.2DispatcherServlet類(lèi)10.1SpringMVC處理流程10.1.1SpringMVC框架的核心是DispatcherServlet,它負(fù)責(zé)攔截請(qǐng)求并將其分派給相應(yīng)的處理器處理。SpringMVC框架處理用戶(hù)請(qǐng)求的過(guò)程模型如圖10-1所示。SpringMVC處理流程10.1.1(1)用戶(hù)在客戶(hù)端發(fā)出一個(gè)HTTP請(qǐng)求,Web容器接收該請(qǐng)求,如果該請(qǐng)求與web.xml中DispatcherServlet的請(qǐng)求映射路徑匹配,容器則將該請(qǐng)求轉(zhuǎn)交給DispatcherServlet處理,它將查找HandlerMapping處理器映射,調(diào)用合適的控制器Controller。(2)控制器Controller根據(jù)請(qǐng)求URL及GET或POST方法調(diào)用合適的業(yè)務(wù)方法對(duì)請(qǐng)求進(jìn)行處理。在業(yè)務(wù)方法中設(shè)置模型數(shù)據(jù),并基于定義的業(yè)務(wù)邏輯向DispatcherServlet返回視圖名。(3)DispatcherServlet在視圖解析器ViewResolver的幫助下選擇為該請(qǐng)求定義的視圖。(4)一旦視圖完成,DispatcherServlet將模型數(shù)據(jù)傳遞給視圖,這些數(shù)據(jù)最終顯示在瀏覽器中。DispatcherServlet類(lèi)在SpringMVC中,對(duì)Web應(yīng)用的設(shè)計(jì)是圍繞DispatcherServlet進(jìn)行,它是一個(gè)前端控制器,它將請(qǐng)求分發(fā)到Controller控制器。DispatcherServlet是SpringMVC的入口,與任何Servlet一樣,必須在部署描述文件web.xml中配置后才能起作用。<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>
<url-pattern>/</url-pattern></servlet-mapping>10.1.2DispatcherServlet類(lèi)
當(dāng)DispatcherServlet初始化時(shí),它將在應(yīng)用程序的WEB-INF目錄下尋找一個(gè)配置文件,該文件命名規(guī)則如下:servletName-servlet.xml
其中,servletName是部署描述文件中DispatcherServlet的名稱(chēng)。如果這個(gè)Servlet名稱(chēng)為springmvc,則配置文件名應(yīng)該為springmvc-servlet.xml,這里的springmvc是DispatcherServlet在<servlet-name>元素中配置的名稱(chēng)。
也可以把SpringMVC的配置文件存放在應(yīng)用的任何目錄中,只要告訴DispatcherServlet如何找到它即可。這只需在<servlet>聲明中使用<init-param>元素定義一個(gè)參數(shù)即可,參數(shù)名為contextConfigLocation,參數(shù)值指定配置文件的路徑。例如,下面代碼將默認(rèn)的配置文件名和路徑改為/WEB-INF/config/sample-config.xml。10.1.2<servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--配置初始化參數(shù)--><init-param><!--加載SpringMVC的xml到Spring的上下文容器中--><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/config/sample-config.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet>案例學(xué)習(xí):簡(jiǎn)單的SpringMVC應(yīng)用10.2本節(jié)開(kāi)發(fā)一個(gè)簡(jiǎn)單的SpringMVC程序,主要介紹DispatcherServlet的配置、控制器的以及視圖的開(kāi)發(fā)。10.2.1創(chuàng)建JakartaEE項(xiàng)目10.2.2在web.xml中配置DispatcherServlet10.2.3創(chuàng)建SpringMVC配置文件10.2.4創(chuàng)建控制器10.2.5創(chuàng)建視圖10.2.6運(yùn)行應(yīng)用程序創(chuàng)建JakartaEE項(xiàng)目在IntelliJIDEA中創(chuàng)建名為chapter10的JakartaEE項(xiàng)目,在版本頁(yè)面選擇JakartaEE9,在pom.xml文件中添加下面依賴(lài)項(xiàng):注意,DispatcherServlet類(lèi)包含在spring-webmvc-6.0.2.jar模塊中。10.2.1<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.2</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.0.2</version></dependency>在web.xml中配置DispatcherServletweb.xml清單10.1DispatcherServlet是SpringMVC的入口,必須在web.xml中配置后才能起作用,web.xml文件的內(nèi)容如清單10.1所示。<?xmlversion="1.0"encoding="UTF-8"?><web-appxmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaeehttps://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"><display-name>SpringMVCApplication</display-name>10.2.2<servlet><servlet-name>springmvc</servlet-name><servlet-class>
org.springframework.web.servlet.DispatcherServlet</servlet-class><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><servlet-mapping><servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern></servlet-mapping></web-app>創(chuàng)建SpringMVC配置文件springmvc-servlet.xml清單10.2由于在web.xml文件中指定了DispatcherServlet名稱(chēng)為springmvc,因此配置文件名應(yīng)該為springmvc-servlet.xml,如清單10.2所示。<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:mvc="/schema/mvc"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd/schema/context/schema/context/spring-context-4.3.xsd10.2.3/schema/mvc/schema/mvc/spring-mvc-4.3.xsd">
<mvc:annotation-driven/><context:component-scanbase-package="com.boda.controller"/><beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="/WEB-INF/jsp/"/><propertyname="suffix"value=".jsp"/></bean></beans>配置文件中配置文件中<mvc:annotation-driven/>用于啟用注解驅(qū)動(dòng)。<context:component-scan/>元素告訴SpringMVC掃描指定包中的類(lèi),這里是com.boda.controller包。<bean>元素配置了視圖解析器InternalResourceViewResolver來(lái)解析視圖,將視圖呈現(xiàn)給用戶(hù)。視圖解析器中配置的prefix屬性值指定視圖的前綴,suffix屬性值指定視圖的后綴。若控制器請(qǐng)求處理方法返回的字符串是hello,經(jīng)過(guò)視圖解析器后,視圖的完整路徑為/WEB-INF/jsp/hello.jsp。創(chuàng)建控制器HelloController.java清單10.3DispatcherServlet將請(qǐng)求動(dòng)作代理給控制器(Controller)執(zhí)行具體的功能。我們?cè)诙x控制器類(lèi)時(shí)使用@Controller注解指明特定的類(lèi)是控制器類(lèi)。使用@RequestMapping注解將一個(gè)URL映射到整個(gè)類(lèi)或某個(gè)特定的處理器方法。下面的HelloController是一個(gè)簡(jiǎn)單的控制器類(lèi)。@ControllerpublicclassHelloController{privatestaticfinalLoglogger=LogFactory.getLog(HelloController.class);
@GetMapping(value="/hello-mvc")publicStringshowHomePage(Modelmodel){("控制器處理請(qǐng)求。");model.addAttribute("message","歡迎學(xué)習(xí)SpringMVC框架!");return"hello";}}10.2.4創(chuàng)建視圖hello.jsp清單10.4SpringMVC支持許多類(lèi)型的視圖實(shí)現(xiàn)表示邏輯。其中包括JSP、HTML、PDF、Excel表格、XML、Velocity模板、XSLT、JSON等等。但最常用的視圖還是JSP頁(yè)面。下面是一個(gè)簡(jiǎn)單的JSP頁(yè)面,它保存在/WEB-INF/jsp/hello.jsp。<%@pagecontentType="text/html;charset=UTF-8"%><html><head><title>HelloSpringMVC</title></head><body><p>${message}</p></body></html>10.2.5運(yùn)行應(yīng)用程序10.2.6要運(yùn)行該程序,打開(kāi)瀏覽器,在地址欄中輸入下面URL,如果一切正常,結(jié)果如圖10-2所示。http://localhost:8080/chapter10/hello-mvc控制器與請(qǐng)求處理方法10.3控制器是SpringMVC應(yīng)用程序的核心組件,Spring使用@Controller注解標(biāo)注控制器類(lèi)。一個(gè)控制器類(lèi)可以處理多個(gè)動(dòng)作,這樣就可以把相關(guān)的動(dòng)作寫(xiě)在一個(gè)控制器類(lèi)中,從而減少應(yīng)用中控制器類(lèi)的數(shù)量。使用@RequestMapping等注解類(lèi)型,一個(gè)方法就可以成為請(qǐng)求處理方法。10.3.1控制器類(lèi)和@Controller注解10.3.2@RequestMapping注解類(lèi)型10.3.3編寫(xiě)請(qǐng)求處理方法10.3.4模型10.3.5視圖解析器(ViewResolver)控制器類(lèi)和@Controller注解在SpringMVC中,控制器類(lèi)使用注解@Controller標(biāo)注,它告訴SpringMVC該類(lèi)的實(shí)例是控制器。下面的CustomerController類(lèi)使用@Controller標(biāo)注。packagecom.boda.controller;importorg.springframework.stereotype.Controller;...@ControllerpublicclassCustomerController{//請(qǐng)求處理方法}10.3.1控制器類(lèi)和@Controller注解SpringMVC使用掃描機(jī)制查找應(yīng)用程序中所有基于注解的控制器類(lèi)。為了保證能夠找到控制器,需要做兩件事。首先,需要在SpringMVC配置文件springmvc-servlet.xml中聲明spring-context模式,如下所示。其次,在配置文件中使用<context:component-scan/>元素,通過(guò)base-package屬性指定控制器類(lèi)所在的包名。例如,如果控制器類(lèi)存儲(chǔ)在com.boda.controller包或其子包中,<component-scan/>元素應(yīng)該如下所示。<beans...xmlns:context="/schema/context"...>
<context:component-scanbase-package="com.boda.controller"/>10.3.1@RequestMapping注解類(lèi)型10.3.2在控制器類(lèi)中需要編寫(xiě)請(qǐng)求處理方法,每個(gè)方法處理一個(gè)動(dòng)作。要告訴SpringMVC哪個(gè)方法處理哪個(gè)動(dòng)作,應(yīng)使用@RequestMapping注解類(lèi)型指定方法映射URI。該注解類(lèi)型用于將一個(gè)請(qǐng)求動(dòng)作映射到一個(gè)方法,該注解類(lèi)型可用于方法和類(lèi)。注解描述@RequestMapping通用的請(qǐng)求處理@GetMapping處理HTTPGET請(qǐng)求@PostMapping處理HTTPPOST請(qǐng)求@PutMapping處理HTTPPUT請(qǐng)求@DeleteMapping處理HTTPDELETE請(qǐng)求@PatchMapping處理HTTPPATCH請(qǐng)求@RequestMapping注解類(lèi)型1.@RequestMapping標(biāo)注方法如果用于方法,該方法即為請(qǐng)求處理方法,即當(dāng)DispatcherServlet接收到與該方法匹配的URI,它將調(diào)用該方法。下面的控制器類(lèi)使用了@RequestMapping注解類(lèi)型。@ControllerpublicclassCustomerController{@RequestMapping(value="/input-customer")publicStringinputCustomer(){//執(zhí)行某些操作return"customerForm";//返回customerForm.jsp視圖頁(yè)面}}10.3.2@RequestMapping注解類(lèi)型上述代碼在inputCustomer()方法上使用@RequestMapping注解,通過(guò)value屬性指定了URI映射,即將input-customer映射到inputCustomer()方法,當(dāng)使用下面的請(qǐng)求URI時(shí),inputCustomer()方法將被調(diào)用。由于value屬性是@RequestMapping注解的默認(rèn)屬性,如果它是注解中唯一屬性,屬性名可以省略。下面兩個(gè)注解含義相同。http://domain/context/input-customer@RequestMapping(value="/input-customer")@RequestMapping("/input-customer")10.3.2@RequestMapping注解類(lèi)型除value屬性外,@RequestMapping注解還有其他屬性。例如,使用method屬性可以指定HTTP方法,這樣用對(duì)應(yīng)的方法處理對(duì)應(yīng)的HTTP請(qǐng)求。例如,下面的processOrder()方法將在處理HTTPPOST或PUT方法時(shí)被調(diào)用。若method屬性?xún)H指定一個(gè)HTTP方法,則大括號(hào)可以省略。@RequestMapping(value="/process-order",method={RequestMethod.POST,RequestMethod.PUT})publicStringprocessOrder(){//執(zhí)行某些操作return"OrderForm";}@RequestMapping(value="/process-order",method=RequestMethod.POST)10.3.2如果沒(méi)有提供method屬性,請(qǐng)求處理方法可處理任何HTTP方法。要限制方法處理某種具體的請(qǐng)求(如GET或POST),還可以使用@GetMapping和@PostMapping等注解。例如,如果inputCustomer()方法僅處理GET請(qǐng)求,則注解可使用如下:@GetMapping(value="/input-customer")publicStringinputCustomer(){//執(zhí)行某些操作return"customerForm";//返回customerForm.jsp視圖頁(yè)面}2.@RequestMapping標(biāo)注類(lèi)@RequestMapping還可以標(biāo)注類(lèi),此時(shí)該注解定義了這個(gè)控制器所處理的根URL路徑。例如,考慮下面控制器類(lèi)的deleteCustomer()方法。@Controller@RequestMapping("/customer")//在類(lèi)的定義上使用@RequestMapping注解publicclassCustomerController{@RequestMapping(value="/delete-customer",method=RequestMethod.POST)publicStringdeleteCustomer(){//執(zhí)行某些操作return"result";}}@RequestMapping注解類(lèi)型
由于控制器類(lèi)被映射到“/customer”,而deleteCustomer()方法被映射到“/delete-customer”,如果要調(diào)用deleteCustomer()方法,應(yīng)當(dāng)使用下面URL。
在類(lèi)級(jí)別使用了@RequestMapping注解后,還可以在方法級(jí)別使用@GetMapping等注解對(duì)方法的處理進(jìn)行細(xì)化。比如,上述代碼中的deleteCustomer()方法就可以使用@PostMapping注解。http://domain/context/customer/delete-customer@PostMapping(value="/delete-customer")publicStringdeleteCustomer(){//執(zhí)行某些操作return"result";}10.3.2在為控制器方法聲明請(qǐng)求映射時(shí),越具體越好。這意味著至少要聲明路徑(也可以從類(lèi)級(jí)別的@RequestMapping繼承一個(gè)路徑)以及它所處理的HTTP方法。一般來(lái)說(shuō),在類(lèi)級(jí)別上使用@RequestMapping注解指定一個(gè)基本路徑,在每個(gè)處理器方法上,使用更具體的@GetMapping或@PostMapping等注解。注解描述@RequestMapping通用的請(qǐng)求處理@GetMapping處理HTTPGET請(qǐng)求@PostMapping處理HTTPPOST請(qǐng)求@PutMapping處理HTTPPUT請(qǐng)求@DeleteMapping處理HTTPDELETE請(qǐng)求@PatchMapping處理HTTPPATCH請(qǐng)求編寫(xiě)請(qǐng)求處理方法請(qǐng)求處理方法可以帶多個(gè)參數(shù)類(lèi)型并返回一個(gè)類(lèi)型。例如,如果在方法中需要訪(fǎng)問(wèn)HttpSession對(duì)象,可以添加一個(gè)HttpSession類(lèi)型的參數(shù),Spring會(huì)將正確的會(huì)話(huà)對(duì)象傳遞給方法。如果方法需要Locale對(duì)象和HttpServletRequest對(duì)象,也可以將它們傳遞給請(qǐng)求處理方法。@RequestMapping("/shopping-cart")publicStringmyMethod(HttpSessionsession){...session.addAttribute(key,value);...}@RequestMapping("/uri")publicStringmyOtherMethod(HttpServletRequestrequest,Localelocale){...//這里可以訪(fǎng)問(wèn)Locale對(duì)象和HttpServletRequest對(duì)象...}10.3.3編寫(xiě)請(qǐng)求處理方法10.3.3下面是可以出現(xiàn)在請(qǐng)求處理方法中常用的參數(shù)類(lèi)型。jakarta.servlet.http.HttpServletRequest或jakarta.servlet.ServletRequestjakarta.servlet.http.HttpServletResponse或jakarta.servlet.ServletResponsejakarta.servlet.http.HttpSessionjava.util.Maporg.springframework.ui.Modelorg.springframework.ui.ModelMap其中最重要的類(lèi)型是org.springframework.ui.Model,它不是ServletAPI類(lèi)型,是SpringMVC類(lèi)型,其中包含Map對(duì)象。當(dāng)請(qǐng)求處理方法每次被調(diào)用時(shí),SpringMVC創(chuàng)建一個(gè)Model對(duì)象并將各種對(duì)象存儲(chǔ)在它的Map對(duì)象中。編寫(xiě)請(qǐng)求處理方法10.3.3請(qǐng)求處理方法可以返回下面類(lèi)型的對(duì)象。Model對(duì)象ModelAndView對(duì)象表示邏輯視圖名的String對(duì)象包含模型屬性的Map對(duì)象在上述所列舉的返回類(lèi)型中,常見(jiàn)的返回類(lèi)型是ModelAndView、String和void。其中ModelAndView類(lèi)型中可以添加Model數(shù)據(jù),并指定視圖;String類(lèi)型的返回值指定跳轉(zhuǎn)視圖,但不能攜帶數(shù)據(jù);而void類(lèi)型主要在異步請(qǐng)求時(shí)使用,它只返回?cái)?shù)據(jù),而不會(huì)跳轉(zhuǎn)視圖。下面示例應(yīng)用中將學(xué)習(xí)如何編寫(xiě)請(qǐng)求處理方法。模型10.3.4在SpringMVC應(yīng)用中經(jīng)常需要存儲(chǔ)模型數(shù)據(jù)。有多種方式存儲(chǔ)模型數(shù)據(jù):使用Model對(duì)象使用ModelMap對(duì)象使用ModelAndView對(duì)象可以使用org.springframework.ui包中的Model對(duì)象和ModelMap對(duì)象存儲(chǔ)模型數(shù)據(jù)。SpringMVC在調(diào)用處理方法之前會(huì)創(chuàng)建一個(gè)隱含的模型對(duì)象作為模型數(shù)據(jù)的存儲(chǔ)容器。如果處理方法的參數(shù)為Model或ModelMap對(duì)象,則SpringMVC會(huì)將隱含模型的引用傳遞給這些參數(shù)。在處理方法內(nèi)部,開(kāi)發(fā)者可以通過(guò)這個(gè)參數(shù)對(duì)象訪(fǎng)問(wèn)模型中的所有數(shù)據(jù),也可以向模型中添加新的屬性數(shù)據(jù)。模型10.3.4Model或ModelMap對(duì)象都可以使用下面方法添加模型數(shù)據(jù):ModeladdAttribute(Stringname,Objectvalue)ModelMapaddAttribute(Stringname,Objectvalue)可以使用org.springframework.web.servlet.ModelAndView對(duì)象表示模型和視圖,該類(lèi)有多個(gè)構(gòu)造方法,如下所示:ModelAndView(Stringname,)ModelAndView(Stringname,String,Object)ModelAndView類(lèi)定義了addObject()方法用于添加模型數(shù)據(jù):ModelAndViewaddObject(Stringname,Objectvalue)UserController.java清單10.5@ControllerpublicclassUserController{privatestaticfinalLoglogger= LogFactory.getLog("UserController.class");@ModelAttributepublicvoiduserModel(Stringusername,Stringpassword,Modelmodel){ ("用戶(hù)模型"); Useruser=newUser(); //用JSP頁(yè)面?zhèn)鱽?lái)的參數(shù)設(shè)置User屬性 user.setUsername(username); user.setPassword(password);model.addAttribute("user",user);}@RequestMapping(value="/input-user",method=RequestMethod.GET)publicStringinputUser(){ ("輸入用戶(hù)"); return"userForm";}@RequestMapping(value="/login-user",method=RequestMethod.POST)publicStringloginUser(Modelmodel){ ("用戶(hù)登錄"); //從Model中返回之前存入的名為user的對(duì)象 Useruser=(User)model.asMap().get("user"); user.setUsername("王小明"); return"showUser";}}視圖解析器(ViewResolver)SpringMVC提供了視圖解析器(viewresolver)以實(shí)現(xiàn)解析ModelAndView模型數(shù)據(jù)到特定視圖上的功能。要使用和配置視圖解析器,需要在配置文件中聲明一個(gè)bean,如下所示:<beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="/WEB-INF/jsp/"/><propertyname="suffix"value=".jsp"/></bean>這里為視圖解析器bean配置prefix和suffix兩個(gè)屬性,分別指定視圖的前綴和后綴,從而可以使視圖的路徑更短。例如,視圖名/WEB-INF/jsp/myPage.jsp就可以簡(jiǎn)單地寫(xiě)成myPage,視圖解析器自動(dòng)添加前綴和后綴。10.3.5請(qǐng)求參數(shù)接收方式10.4對(duì)客戶(hù)傳遞的請(qǐng)求參數(shù),需要使用控制器(Controller)接收,然后控制器對(duì)其進(jìn)行處理。在SpringMVC中,控制器有多種方法接收請(qǐng)求參數(shù),有的適合GET請(qǐng)求,有的適合POST請(qǐng)求,有的二者都適合。10.4.1用HttpServletRequest接收參數(shù)10.4.2用簡(jiǎn)單數(shù)據(jù)類(lèi)型接收請(qǐng)求參數(shù)10.4.3用POJO對(duì)象接收請(qǐng)求參數(shù)10.4.4用@PathVariable接收URL中參數(shù)用HttpServletRequest接收參數(shù)可以通過(guò)表單向控制器傳遞請(qǐng)求參數(shù),也可以通過(guò)URL向控制器傳遞請(qǐng)求參數(shù)。請(qǐng)求參數(shù)在URL中是&符號(hào)分隔的一組“鍵/值”對(duì)。例如,下面URL帶一個(gè)id請(qǐng)求參數(shù),它的值是103。請(qǐng)求參數(shù)被封裝在HttpServletRequest請(qǐng)求對(duì)象中,因此可以通過(guò)它獲取客戶(hù)傳遞來(lái)的請(qǐng)求參數(shù)。具體方法是為請(qǐng)求處理方法傳遞一個(gè)HttpServletRequest對(duì)象,然后在請(qǐng)求處理方法中調(diào)用請(qǐng)求對(duì)象的getParameter()方法檢索指定的請(qǐng)求參數(shù)。http://localhost:8080/chapter10/search-customer?id=103Stringid=request.getParameter("id");10.4.1用簡(jiǎn)單數(shù)據(jù)類(lèi)型接收請(qǐng)求參數(shù)這種方法是在請(qǐng)求處理方法中使用與請(qǐng)求參數(shù)同名的形參接收請(qǐng)求參數(shù)值,這里要求方法參數(shù)名與請(qǐng)求參數(shù)名相同。如下面的saveCustomer()方法所示。@RequestMapping(value="/save-customer")publicStringsaveCustomer(Stringid,Stringname,Stringaddress,doublebalance,Modelmodel){("調(diào)用saveCustomer()方法");Customercustomer=newCustomer();customer.setId(id);customer.setName(name);customer.setAddress(address);customer.setBalance(balance);//將customer對(duì)象存儲(chǔ)到模型對(duì)象中model.addAttribute("customer",customer);return"showCustomer";}10.4.2
需要注意的是,有時(shí)請(qǐng)求參數(shù)名與方法中形參名不一致,這會(huì)導(dǎo)致后臺(tái)無(wú)法正確綁定并接收前端請(qǐng)求參數(shù)。為此,SpringMVC提供了@RequestParam注解來(lái)進(jìn)行間接數(shù)據(jù)綁定。
使用org.springframework.web.bind.annotation.RequestParam注解類(lèi)型標(biāo)注一個(gè)參數(shù),請(qǐng)求參數(shù)值將拷貝到該參數(shù)中。
例如,下面方法包含4個(gè)請(qǐng)求參數(shù),它將請(qǐng)求參數(shù)值存儲(chǔ)到對(duì)應(yīng)變量中。publicStringsaveCustomer(@RequestParam(value="d")Stringc_id, @RequestParam(value="name")Stringc_name, @RequestParam(value="address")Stringc_address, @RequestParam(value="balance")doublec_balance,Modelmodel)用POJO對(duì)象接收請(qǐng)求參數(shù)
在SpringMVC中,還可以把請(qǐng)求參數(shù)自動(dòng)綁定到POJO的屬性上。這是將所有關(guān)聯(lián)的請(qǐng)求參數(shù)封裝到一個(gè)POJO中,在請(qǐng)求處理方法中直接使用該P(yáng)OJO作為形參來(lái)完成數(shù)據(jù)綁定。這種方法適合GET請(qǐng)求和POST請(qǐng)求。需要注意的是,POJO對(duì)象的屬性名稱(chēng)必須與請(qǐng)求參數(shù)名相同。下面代碼使用Customer對(duì)象接收請(qǐng)求參數(shù)。@RequestMapping(value="/save-customer")publicStringsaveCustomer(Customercustomer,Modelmodel){("調(diào)用saveCustomer()方法");//將customer對(duì)象存儲(chǔ)到模型對(duì)象中model.addAttribute("customer",customer);return"showCustomer";}10.4.3用@PathVariable接收URL中參數(shù)用路徑變量傳遞請(qǐng)求參數(shù)。路徑變量與請(qǐng)求參數(shù)類(lèi)似,但它不需要參數(shù)名,僅需提供一個(gè)參數(shù)值。例如,前面例子中search-customer動(dòng)作被映射到下面的URL。http://localhost:8080/chapter10/search-customer/103這里,103就是一個(gè)路徑變量值,在請(qǐng)求search-customer動(dòng)作時(shí)將其傳遞給請(qǐng)求處理方法中對(duì)應(yīng)的路徑變量中。下面的searchCustomer()方法指定了路徑變量id。10.4.4@RequestMapping(value="/search-customer/{id}")publicStringsearchCustomer(@PathVariableStringid,Modelmodel){Customercustomer=customerService.get(id);model.addAttribute("customer",customer);return"customerView";}使用路徑變量,首先在@RequestMapping注解的value屬性值中添加一個(gè)變量,該變量必須放在一對(duì)大括號(hào)中。例如,上面代碼的@RequestMapping注解中使用了一個(gè)名為id的路徑變量。在方法聲明中使用@PathVariable注解標(biāo)注一個(gè)參數(shù)變量id。當(dāng)該方法被調(diào)用時(shí),請(qǐng)求URL中的id值將被傳遞給方法的路徑變量id,然后在方法中使用。路徑變量的類(lèi)型不一定是String。SpringMVC將進(jìn)行自動(dòng)轉(zhuǎn)換。在請(qǐng)求中還可以使用多個(gè)路徑變量。例如,下面定義了兩個(gè)路徑變量:userId和OrderId。@RequestMapping(value="/product_view/{userId}/{orderId}")轉(zhuǎn)發(fā)、重定向與Flash屬性在SpringMVC框架中,控制器的請(qǐng)求處理方法的return語(yǔ)句默認(rèn)就是請(qǐng)求轉(zhuǎn)發(fā),只不過(guò)轉(zhuǎn)發(fā)的目標(biāo)是視圖。如下代碼所示。@RequestMapping(value="/user-register")publicStringuserRegister(){//注冊(cè)代碼return"register";//控制轉(zhuǎn)發(fā)到register.jsp頁(yè)面}10.5在請(qǐng)求處理方法中還可以使用下面語(yǔ)句將請(qǐng)求轉(zhuǎn)發(fā)到控制器的另一個(gè)請(qǐng)求方法:return"forward:showUser";重定向是客戶(hù)端行為,請(qǐng)求作用域中變量在轉(zhuǎn)發(fā)到的資源將不可用,存儲(chǔ)在會(huì)話(huà)作用域中變量可用。在有些環(huán)境下使用重定向可能更好,比如將控制重定向到外部資源,如另一個(gè)Web站點(diǎn),這時(shí)就不能使用轉(zhuǎn)發(fā)。為了避免這種情況,表單提交后,應(yīng)該將用戶(hù)重定向到一個(gè)不同的頁(yè)面。這個(gè)頁(yè)面多次加載不產(chǎn)生副作用。在前面例子中CustomerController類(lèi)的saveCustomer()方法中如果使用重定向,return語(yǔ)句應(yīng)該如下:return"redirect:/show-customer/"+customer.getId();要使用Flash屬性,在SpringMVC配置文件中必須使用<annotation-driven/>元素。然后,在請(qǐng)求處理方法中添加一個(gè)org.springframework.web.servlet.mvc.support.RedirectAttributes類(lèi)型的參數(shù)。下面代碼演示了Flash屬性的使用。@RequestMapping(value="save-customer",method=RequestMethod.POST)publicStringsaveCustomer(Customercustomer,RedirectAttributesredirectAttributes){("調(diào)用saveCustomer()方法");//保存customer對(duì)象CustomersavedCustomer=customerService.add(customer);redirectAttributes.addFlashAttribute("message","Thecustomerwassuccessfullyadded.");return"redirect:/view-customer/"+savedCustomer.getId();}可以使用HttpSession對(duì)象存儲(chǔ)有關(guān)數(shù)據(jù),然后在目標(biāo)視圖中使用EL表達(dá)式檢索出來(lái)。publicStringsaveCustomer(Customercustomer,HttpSessionsession){("調(diào)用saveCustomer()方法");//保存customer對(duì)象CustomersavedCustomer=customerService.add(customer);session.setAttribute("customer",customer);return"redirect:/view-customer/"+savedCustomer.getId();}用@Autowired和@Service進(jìn)行依賴(lài)注入
使用Spring框架的好處之一是容易使用依賴(lài)注入,畢竟Spring從一開(kāi)始就是一個(gè)依賴(lài)注入容器。將一個(gè)依賴(lài)注入到SpringMVC控制器中最容易的方法是使用@Autowired注解標(biāo)注一個(gè)字段或一個(gè)方法。該注解定義在org.springframework.beans.factory.annotation包中。
要使一個(gè)依賴(lài)被找到,它的類(lèi)必須使用@Service注解,它定義在org.springframework.stereotype包中。該注解類(lèi)型表示類(lèi)是一個(gè)服務(wù)類(lèi)。
此外,在配置文件中需要添加<component-scan/>元素掃描依賴(lài)類(lèi)所在包。<context:component-scanbase-package="dependencyPackage"/>10.6作為示例,下面的CustomerController控制器類(lèi)使用了@Autowired注解注入一個(gè)Service對(duì)象。CustomerController.java清單10.6@ControllerpublicclassCustomerController{privatestaticfinalLoglogger=LogFactory.getLog(CustomerController.class);@AutowiredprivateCustomerServicecustomerService;@RequestMapping(value="/input-customer")publicStringinputCustomer(){("inputCustomercalled");return"inputCustomer";}@RequestMapping(value="/save-customer",method=RequestMethod.POST)publicStringsaveCustomer(Customercustomer,RedirectAttributesredirectAttributes){("saveCustomercalled");//addcustomerCustomersavedCustomer=customerService.addCustomer(customer);redirectAttributes.addFlashAttribute("message","Theproductwassuccessfullyadded.");return"redirect:/view-customer/"+savedCustomer.getId();}
@RequestMapping(value="/view-customer/{id}")publicStringviewCustomer(@PathVariableLongid,Modelmodel){Customercustomer=customerService.getCustomer(id);model.addAttribute("customer",customer);return"showCustomer";}用@Autowired和@Service進(jìn)行依賴(lài)注入CustomerService.java清單10.7下面清單給出了CustomerService接口及實(shí)現(xiàn)類(lèi)。注意,要使實(shí)現(xiàn)類(lèi)被掃描到,它必須使用@Service注解標(biāo)注。importcom.boda.domain.Customer;publicinterfaceCustomerService{CustomeraddCustomer(Customercustomer
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版店面裝修轉(zhuǎn)讓合同
- 外國(guó)人勞務(wù)合同
- 2024年濕地保護(hù)與恢復(fù)項(xiàng)目支出績(jī)效評(píng)價(jià)報(bào)告
- 體育與健身教學(xué)進(jìn)度表
- 小學(xué)體育四年級(jí)第二學(xué)期教學(xué)進(jìn)度表
- 小產(chǎn)權(quán)房購(gòu)房協(xié)議書(shū)范本
- 學(xué)前教育史教學(xué)大綱
- 保稅倉(cāng)合同樣本
- ktv設(shè)備合同標(biāo)準(zhǔn)文本
- 供油協(xié)議-合同樣本
- 2023版藥品生產(chǎn)質(zhì)量管理規(guī)范 附錄1 無(wú)菌藥品
- 2023年新疆鐵道職業(yè)技術(shù)學(xué)院?jiǎn)握忻嬖嚹M試題及答案解析
- 天星鄉(xiāng)養(yǎng)羊項(xiàng)目績(jī)效評(píng)價(jià)報(bào)告
- GB/T 39489-2020全尾砂膏體充填技術(shù)規(guī)范
- 《民法》全冊(cè)精講課件
- 廠(chǎng)內(nèi)機(jī)動(dòng)車(chē)輛課件
- 四川方言詞典(教你說(shuō)一口地道的四川話(huà))
- 企業(yè)標(biāo)準(zhǔn)編寫(xiě)模板
- 《新媒體運(yùn)營(yíng)》考試參考題庫(kù)(含答案)
- 學(xué)校食堂餐廚具操作規(guī)程
- DB32T 3916-2020 建筑地基基礎(chǔ)檢測(cè)規(guī)程
評(píng)論
0/150
提交評(píng)論