JavaWeb及其框架技術(shù) 課件 第9章 Spring MVC框架的使用_第1頁(yè)
JavaWeb及其框架技術(shù) 課件 第9章 Spring MVC框架的使用_第2頁(yè)
JavaWeb及其框架技術(shù) 課件 第9章 Spring MVC框架的使用_第3頁(yè)
JavaWeb及其框架技術(shù) 課件 第9章 Spring MVC框架的使用_第4頁(yè)
JavaWeb及其框架技術(shù) 課件 第9章 Spring MVC框架的使用_第5頁(yè)
已閱讀5頁(yè),還剩53頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第9章SpringMVC框架的使用掌握MVC模式的設(shè)計(jì)思想掌握SpringMVC框架的相關(guān)組件及簡(jiǎn)單應(yīng)用開(kāi)發(fā)掌握SpringMVC框架的工作機(jī)制掌握SpringMVC框架控制器的開(kāi)發(fā)掌握SpringMVC框架注解風(fēng)格的開(kāi)發(fā)掌握SpringMVC框架處理器攔截器及異常處理器的應(yīng)用學(xué)習(xí)目標(biāo)MVC設(shè)計(jì)模式是常用的設(shè)計(jì)模式之一,將整個(gè)程序分為3個(gè)層次:模型(Model)層、視圖(View)層與控制器(Controller)層。模型層負(fù)責(zé)處理程序需要的數(shù)據(jù)或信息;控制器層負(fù)責(zé)接收用戶發(fā)送的請(qǐng)求,獲取模型層中的數(shù)據(jù),然后對(duì)其進(jìn)行相應(yīng)的操作;視圖層負(fù)責(zé)為用戶提供操作界面和展示數(shù)據(jù),會(huì)將最終的數(shù)據(jù)渲染到視圖頁(yè)面上,最后展示給用戶;MVC設(shè)計(jì)模式中各組件的交互如圖9-1所示。9.1MVC設(shè)計(jì)模式圖9-1MVC設(shè)計(jì)模式中各組件的交互我們?cè)陂_(kāi)發(fā)一個(gè)Web項(xiàng)目的時(shí)候,通常也會(huì)采用分層的思想,將代碼分成DAO層、Service層、Controller層。DAO層是數(shù)據(jù)訪問(wèn)層(DataAccessObject),這一層中包含一些對(duì)數(shù)據(jù)的操作代碼,如對(duì)某個(gè)表的增刪改查,大多數(shù)情況下DAO層中的類和數(shù)據(jù)庫(kù)中的表一一對(duì)應(yīng)。Service層是服務(wù)層,能夠?qū)⒁粋€(gè)或多個(gè)DAO類的基礎(chǔ)數(shù)據(jù)操作方法封裝成一個(gè)服務(wù)方法,并將一系列對(duì)數(shù)據(jù)的基礎(chǔ)操作代碼封裝成一系列服務(wù)。Controller層是控制層,負(fù)責(zé)請(qǐng)求轉(zhuǎn)發(fā),接受頁(yè)面?zhèn)鱽?lái)的參數(shù),并將這些參數(shù)傳給Service層處理,最后接收到Service層的返回值再傳給頁(yè)面。這種將程序的輸入輸出、數(shù)據(jù)處理及數(shù)據(jù)展示分離開(kāi)來(lái)的設(shè)計(jì)模式使程序結(jié)構(gòu)變得靈活且清晰,同時(shí)也描述了程序各對(duì)象間的通信方式,降低了程序的耦合度,有助于后期的程序維護(hù)。9.1MVC設(shè)計(jì)模式SpringMVC框架是包含在Spring框架中的一個(gè)基于MVC設(shè)計(jì)思想的Web應(yīng)用程序框架,目的是簡(jiǎn)化開(kāi)發(fā)工作、提高開(kāi)發(fā)效率。SpringMVC框架本質(zhì)上可以認(rèn)為是對(duì)JavaWeb中Servlet對(duì)象的封裝,從而簡(jiǎn)化了對(duì)Servlet對(duì)象的開(kāi)發(fā)。SpringMVC框架將HTTP請(qǐng)求分派給處理程序并返回相應(yīng)的響應(yīng)數(shù)據(jù),其中可配置內(nèi)容有處理程序映射、視圖解析、區(qū)域設(shè)置、時(shí)區(qū)和主題解析等。其主要入口是DispatcherServlet類(前端控制器),SpringMVC框架在容器初始化時(shí),會(huì)調(diào)用DispatcherServlet類的onRefresh()方法,通過(guò)initStrategies()方法來(lái)初始化SpringMVC框架的各個(gè)組件。SpringMVC框架有MultipartResolver、LocaleResolver、ThemeResolver、HandlerMapping、HandlerAdapter、HandlerExceptionResolver、RequestToViewNameTranslator、ViewResolver、FlashMapManager九大組件。9.2SpringMVC框架的介紹DispatcherServlet類的部分源碼如下。9.2SpringMVC框架的介紹protectedvoidonRefresh(ApplicationContextcontext){this.initStrategies(context);}protectedvoidinitStrategies(ApplicationContextcontext){this.initMultipartResolver(context);this.initLocaleResolver(context);this.initThemeResolver(context);this.initHandlerMappings(context);this.initHandlerAdapters(context);this.initHandlerExceptionResolvers(context);this.initRequestToViewNameTranslator(context);this.initViewResolvers(context);this.initFlashMapManager(context);}SpringMVC框架的九大組件說(shuō)明如表9-1所示。9.2SpringMVC框架的介紹組件名功能說(shuō)明MultipartResolver多文件上傳組件。將enctype為“multipart/form-data”的表單的Request請(qǐng)求包裝成multipartHttpServletRequest對(duì)象LocaleResolver多語(yǔ)言支持組件。用于支持國(guó)際化多語(yǔ)言切換,主要作用是從Request請(qǐng)求中解析出local參數(shù)的值ThemeResolver主題模板處理組件。主要用于支持Web頁(yè)面的多主題風(fēng)格,可以通過(guò)themeResolver對(duì)象來(lái)讀取和解析頁(yè)面主題樣式配置HandlerMapping處理器映射器組件。主要用來(lái)保存URL和業(yè)務(wù)邏輯的對(duì)應(yīng)關(guān)系,它本質(zhì)上就是一個(gè)Map對(duì)象,Key為URL地址,Value為對(duì)應(yīng)Controller層中的處理方法HandlerAdapter處理器適配器組件。主要功能是動(dòng)態(tài)解析參數(shù)及動(dòng)態(tài)適配業(yè)務(wù)邏輯對(duì)應(yīng)的HandlerHandlerExceptionResolver異常處理器組件。主要功能是對(duì)不同的異常進(jìn)行攔截,并實(shí)現(xiàn)對(duì)異常個(gè)性化處理的目的,可以給不同的異常配置不同的modelAndView對(duì)象。handlerExceptionResolver對(duì)象根據(jù)異常類型,將處理封裝為一個(gè)modelAndView對(duì)象,從而將異常信息轉(zhuǎn)換為更加友好的Web頁(yè)面展示RequestToViewNameTranslator視圖名稱提取組件。主要功能是從Request請(qǐng)求中提取viewName。這個(gè)viewName可以設(shè)置在URL參數(shù)上,也可以設(shè)置在Request請(qǐng)求的Header屬性上ViewResolver視圖渲染組件。其作用相當(dāng)于模板引擎,就是根據(jù)視圖名稱找到視圖對(duì)應(yīng)的模板文件,然后進(jìn)行解析FlashMapManager閃存管理組件。其相當(dāng)于一個(gè)參數(shù)緩存器,用來(lái)保證請(qǐng)求跳轉(zhuǎn)過(guò)程中參數(shù)不丟失,可以用Redirect(重定向)做到和Forward(轉(zhuǎn)發(fā))同樣的效果9.3.1SpringMVC框架的工作機(jī)制SpringMVC框架的工作機(jī)制本質(zhì)上就是其五大組件交互的過(guò)程,如圖9-2所示。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例圖9-2SpringMVC框架的工作機(jī)制(1)客戶端向服務(wù)器發(fā)起請(qǐng)求,前端控制器(DispatcherServlet)攔截用戶的請(qǐng)求。(2)前端控制器請(qǐng)求處理器映射器(HandlerMappering)查找處理器(Handler):通過(guò)XML配置或注解進(jìn)行查找。(3)找到處理器(Handler)后,處理器映射器(HandlerMappering)向前端控制器返回處理器執(zhí)行鏈(HandlerExecutionChain)。(4)前端控制器(DispatcherServlet)調(diào)用處理器適配器(HandlerAdapter)。(5)處理器適配器將請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)的處理器方法進(jìn)行處理,這里執(zhí)行的處理器就是Controller中定義的方法。(6)處理器執(zhí)行完畢后,向處理器適配器返回modelAndView對(duì)象。(7)處理器適配器向前端控制器返回modelAndView對(duì)象。(8)前端控制器請(qǐng)求視圖解析器(ViewResolver)進(jìn)行視圖解析。(9)視圖解析器找到對(duì)應(yīng)的視圖后,向前端控制器返回視圖(View)。(10)前端控制器對(duì)視圖(View)進(jìn)行渲染后向客戶端返回響應(yīng)結(jié)果。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例9.3.2開(kāi)發(fā)一個(gè)SpringMVC框架的簡(jiǎn)單應(yīng)用程序1.創(chuàng)建項(xiàng)目打開(kāi)IDEA創(chuàng)建一個(gè)Java項(xiàng)目,輸入項(xiàng)目名稱為“springmvc-demo”。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例2.添加框架支持(1)在IDEA中右擊項(xiàng)目文件夾→選擇“AddFrameworksSupport”。(2)在“AddFrameworksSupport”窗口中勾選WebAppliaction、Spring和SpringMVC三項(xiàng),然后點(diǎn)擊“OK”按鈕(見(jiàn)圖9-3)。(3)IDEA會(huì)自動(dòng)生成一個(gè)基于SpringMVC框架的Web項(xiàng)目目錄結(jié)構(gòu),如圖9-4所示。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例圖9-4IDEA生成的基于SpringMVC框架的Web項(xiàng)目目錄結(jié)構(gòu)3.編輯web.xml配置文件找到“web/WEB-INF/web.xml”配置文件,并進(jìn)行如下操作。(1)在Servlet標(biāo)簽下配置一個(gè)SpringMVC框架的前端控制器(dispatcherServlet對(duì)象);在init-param標(biāo)簽下配置contextConfigLocation參數(shù),設(shè)置SpringMVC框架配置文件的路徑;將load-on-startup的值設(shè)置為1,讓W(xué)eb服務(wù)器一啟動(dòng)就加載前端控制器這個(gè)對(duì)象。(2)在servlet-mapping標(biāo)簽中配置前端控制器需要攔截的路徑。這里把路徑設(shè)置成“.form”形式,SpringMVC框架的前端控制器就會(huì)攔截后綴為“.form”的請(qǐng)求,讓這些請(qǐng)求找到可執(zhí)行的處理程序。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例例9-1編寫(xiě)web.xml配置文件。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例<?xmlversion="1.0"encoding="UTF-8"?>

<web-appxmlns="/xml/ns/javaee"

xmlns:xsi="/2001/XMLSchema-instance"

xsi:schemaLocation="/xml/ns/javaee

/xml/ns/javaee/web-app_4_0.xsd"

version="4.0">

<!--配置Servlet容器的參數(shù):設(shè)置Spring配置文件的位置-->

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/applicationContext.xml</param-value>

</context-param>

<!--配置Servlet容器的監(jiān)聽(tīng)器:讓Servlet容器在創(chuàng)建時(shí)加載Spring配置文件-->

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<!--配置SpringMVC的前端控制器-->

<servlet>

<servlet-name>dispatcher</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<!--設(shè)置初始化參數(shù):SpringMVC配置文件的路徑-->

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>

</init-param>

<!--設(shè)置Servlet容器啟動(dòng)時(shí)加載前端控制器-->

<load-on-startup>1</load-on-startup>

</servlet>

<!--配置前端控制器攔截的路徑-->

<servlet-mapping>

<servlet-name>dispatcher</servlet-name>

<url-pattern>*.form</url-pattern>

</servlet-mapping>

</web-app>4.編輯項(xiàng)目的配置文件dispatcher-servlet.xml找到“web/WEB-INF/dispatcher-servlet.xml”配置文件,具體操作步驟如下。(1)添加<mvc:annotation-driven>標(biāo)簽,開(kāi)啟注解驅(qū)動(dòng)支持。添加后SpringMVC框架會(huì)自動(dòng)注冊(cè)requestMappingHandlerMapping對(duì)象與requestMappingHandlerAdapter對(duì)象兩個(gè)bean,這是SpringMVC框架分發(fā)請(qǐng)求必需的,并且提供了數(shù)據(jù)綁定、@NumberFormatannotation、@DateTimeFormat、@Valid、讀寫(xiě)XML的支持,以及讀寫(xiě)JSON的支持(默認(rèn)為Jackson)等功能。(2)添加<context:component-scan>標(biāo)簽,開(kāi)啟組件掃描,設(shè)置SpringMVC框架掃描controller對(duì)象相關(guān)的注解。(3)配置一個(gè)“org.springframework.web.servlet.view.InternalResourceViewResolver”視圖解析器,prefix配置視圖的路徑前綴,suffix配置視圖的后綴,讓SpringMVC框架可以找到視圖位置。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例例9-2編寫(xiě)dispatcher-servlet.xml配置文件。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="/schema/beans"

xmlns:xsi="/2001/XMLSchema-instance"

xmlns:mvc="/schema/mvc"

xmlns:context="/schema/context"

xsi:schemaLocation="/schema/beans

/schema/beans/spring-beans.xsd

/schema/mvc

/schema/mvc/spring-mvc.xsd

/schema/context

/schema/context/spring-context.xsd">

<!--開(kāi)啟注解驅(qū)動(dòng)支持-->

<mvc:annotation-driven/>

<!--開(kāi)啟組件掃描:設(shè)置SpringMVC只掃描Controller相關(guān)的注解-->

<context:component-scanbase-package="org.example.controller"/>

<!--配置視圖解析器:讓SpringMVC可以找到視圖位置-->

<beanid="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<propertyname="prefix"value="/views/"/>

<propertyname="suffix"value=".jsp"/>

</bean>

</beans>5.編寫(xiě)Controller類在src文件夾下新建org.example.controller包,在org.example.controller包下創(chuàng)建一個(gè)Controller類,用@Controller注解聲明這是一個(gè)Controller類,@RequestMapping("/user")定義訪問(wèn)這個(gè)控制器的父級(jí)路徑,如例9-3所示。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例@Controller

@RequestMapping("/user")

publicclassUserController{

@RequestMapping(value="/list",method=RequestMethod.GET)

publicStringuserList(){

System.out.println("獲取用戶列表...");

//返回userList.jsp視圖

return"userList";

}

}6.創(chuàng)建視圖在web文件夾下創(chuàng)建一個(gè)views文件夾,然后在views文件夾下創(chuàng)建一個(gè)userList.jsp視圖頁(yè)面,這里簡(jiǎn)單地在頁(yè)面中用文字來(lái)展示,如例9-4所示。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例<%@pagecontentType="text/html;charset=UTF-8"language="java"%>

<html>

<head>

<title>$Title$</title>

</head>

<body>

<h1>用戶列表頁(yè)面</h1>

</body>

</html>7.最終的目錄結(jié)構(gòu)展示最終,基于SpringMVC框架的Web項(xiàng)目目錄結(jié)構(gòu)展示如圖9-5所示。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例圖9-5Web項(xiàng)目目錄結(jié)構(gòu)展示8.部署項(xiàng)目這里通過(guò)IDEA將項(xiàng)目部署到Tomcat服務(wù)器中,具體步驟如下。(1)點(diǎn)擊IDEA中的快捷運(yùn)行欄菜單“Addconfigurations”,打開(kāi)IDEA部署配置頁(yè),如圖9-6所示。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例圖9-6通過(guò)點(diǎn)擊“Addconfigurations”(2)點(diǎn)擊“+”添加一個(gè)Tomcat服務(wù)器,配置Server環(huán)境,如圖9-7所示。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例圖9-7添加并配置一個(gè)Tomcat服務(wù)器(3)在IDEA的Tomcat服務(wù)器配置中,通過(guò)配置頁(yè)面的Deployment選項(xiàng)部署該項(xiàng)目,如圖9-8所示。這里部署的war包是一個(gè)完整的Web應(yīng)用程序,是一個(gè)可以在Web容器中直接運(yùn)行的模塊,它包含Servlet對(duì)象、HTML頁(yè)面、Java類、圖像文件,以及組成Web應(yīng)用程序的其他資源。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例9.訪問(wèn)控制器(Controller)啟動(dòng)項(xiàng)目,訪問(wèn)控制器(Controller)。通過(guò)IDEA將項(xiàng)目部署到Tomcat服務(wù)器后,便可以在IDEA中啟動(dòng)該項(xiàng)目了。我們使用瀏覽器訪問(wèn)http://localhost:8080/springmvc_demo_war_exploded/user/list.form,便可以發(fā)送請(qǐng)求到項(xiàng)目中的UserController控制器。在瀏覽器中可以看到UserController控制器返回了一個(gè)userList.html視圖頁(yè)面,如圖9-9所示。同時(shí)觀察Tomcat服務(wù)器的運(yùn)行后臺(tái),可以看到UserController控制器中定義的輸出語(yǔ)句成功執(zhí)行,如圖9-10所示。9.3SpringMVC框架的工作機(jī)制與應(yīng)用示例9.4.1@Controller注解@Controller是類級(jí)別的注解,該注解裝飾的類將作為一個(gè)Controller類。從SpringMVC框架的源碼中可以看到,@Controller注解就是@Component注解的別名,給它起別名是為了讓SpringMVC框架區(qū)分這是Controller類,由SpringMVC框架加載這個(gè)類,而不是讓Spring框架加載bean。9.4基于注解的SpringMVC框架開(kāi)發(fā)@Controller源碼如下。

@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public@interfaceController{ @AliasFor(annotation=Component.class) Stringvalue()default""; }9.4.2@RequestMapping注解@RequestMapping注解是類級(jí)別和方法級(jí)別的注解,將URL映射到整個(gè)類或特定的處理程序方法中。該注解通常裝飾在類上,用來(lái)表示URL的路徑前綴;該注解裝飾在方法上可以指定請(qǐng)求方法(GET請(qǐng)求、POST請(qǐng)求等)、請(qǐng)求參數(shù)條件和URL子路徑。例9-5演示了@Controller注解和@RequestMapping注解的使用,在Controller類上寫(xiě)了@RequestMapping("/user"),在方法中寫(xiě)了@RequestMapping(value="/save",method={RequestMethod.POST})。我們?cè)谠L問(wèn)這個(gè)處理器方法時(shí)需要使用POST請(qǐng)求方式,訪問(wèn)地址http://localhost:8080/springmvc_demo_war_exploded/user/save.form(這里有“.form”后綴,是因?yàn)樵谇岸丝刂破髦性O(shè)置了需要攔截的路徑,見(jiàn)例9-1的web.xml配置文件中對(duì)前端控制器的配置)。9.4基于注解的SpringMVC框架開(kāi)發(fā)例9-5@Controller注解和@RequestMapping注解的使用9.4基于注解的SpringMVC框架開(kāi)發(fā)@Controller

@RequestMapping("/user")

publicclassUserController{

//例9-5使用

@RequestMapping(value="/save",method={RequestMethod.POST})

publicvoidsaveUser(){

System.out.println("保存用戶...");

}

}SpringMVC框架支持方法級(jí)組合的注解,有助于簡(jiǎn)化常見(jiàn)的HTTP請(qǐng)求方法和更好地表達(dá)帶批注的處理程序方法的語(yǔ)義,如@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping等一系列注解。例9-6演示@GetMapping、@PostMapping、@PutMapping、@DeleteMapping注解的使用。9.4基于注解的SpringMVC框架開(kāi)發(fā)@Controller

@RequestMapping("/user")

publicclassUserController{

//@GetMapping等價(jià)于@RequestMapping(method={RequestMethod.GET})

@GetMapping

publicvoidgetUser(){

System.out.println("獲取用戶...");

}

//@PostMapping("/save")等價(jià)于@RequestMapping(value="/save",method={RequestMethod.Post})

@PostMapping("/save")

publicvoidsaveUser(){

System.out.println("保存用戶...");

}

//@PutMapping("/update")等價(jià)于@RequestMapping(value="/update",method={RequestMethod.Put})

@PutMapping("/update")

publicvoidupdateUser(){

System.out.println("修改用戶...");

}

//@DeleteMapping("/delete")等價(jià)于@RequestMapping(value="/delete",method={RequestMethod.Delete})

@DeleteMapping("/delete")

publicvoiddeleteUser(){

System.out.println("刪除用戶...");

}

}9.4.3@SessionAttribute注解和@SessionAttributes注解@SessionAttributes注解是類級(jí)別的注解,該注解用在Controller類上,用來(lái)在多個(gè)請(qǐng)求之間共享數(shù)據(jù),將Model數(shù)據(jù)存儲(chǔ)在session對(duì)象中。@SessionAttribute是方法級(jí)別的注解,該注解用在控制器方法的參數(shù)列表中,用來(lái)讀取已經(jīng)保存在session對(duì)象中的數(shù)據(jù)。例9-7演示了@SessionAttribute注解和@SessionAttributes注解的使用,在UserController控制器類上寫(xiě)了@SessionAttributes("user"),這指的是將modelMap對(duì)象中key為user的Model數(shù)據(jù)共享到session對(duì)象中;而getUser()方法上的@SessionAttribute("user")是要從session對(duì)象中獲取key為user的數(shù)據(jù),并將其注入到user對(duì)象中。9.4基于注解的SpringMVC框架開(kāi)發(fā)例9-7演示@SessionAttribute注解和@SessionAttributes注解的使用。9.4基于注解的SpringMVC框架開(kāi)發(fā)@Controller

@RequestMapping("/user")

@SessionAttributes("user")//將modelMap對(duì)象中key為user的Model數(shù)據(jù)共享到session對(duì)象中

publicclassUserController{

@PostMapping("/save")

publicStringsaveUser(ModelMapmodel){

//向modelMap對(duì)象中添加key為user的屬性

model.addAttribute("user",newUser("張三",18));

return"result";

}

@GetMapping

//@SessionAttribute從session對(duì)象中獲取數(shù)據(jù),并將其注入到user對(duì)象中

publicStringgetUser(@SessionAttribute("user")Useruser){

System.out.println(user);

return"result";

}

}9.4.4控制器方法中處理請(qǐng)求方法的參數(shù)類型控制器方法中處理請(qǐng)求方法的參數(shù)類型主要有請(qǐng)求對(duì)象、響應(yīng)對(duì)象、會(huì)話對(duì)象、模型對(duì)象、流對(duì)象和實(shí)體類對(duì)象,相關(guān)說(shuō)明如表9-2所示。9.4基于注解的SpringMVC框架開(kāi)發(fā)參數(shù)類型功能說(shuō)明請(qǐng)求對(duì)象ServletRequest類和HttpServletRequest類都代表請(qǐng)求對(duì)象。HttpServletRequest類繼承自ServletRequest類,比ServletRequest類多了一些針對(duì)HTTP協(xié)議的方法。可以用來(lái)獲取請(qǐng)求中的相關(guān)數(shù)據(jù)響應(yīng)對(duì)象ServletResponse類和HttpServletResponse類都代表響應(yīng)對(duì)象,HttpServletResponse類繼承自ServletResponse類,比ServletResponse類多了一些針對(duì)HTTP協(xié)議的方法??梢杂脕?lái)設(shè)置響應(yīng)的相關(guān)數(shù)據(jù)會(huì)話對(duì)象HttpSession類代表會(huì)話對(duì)象,可以用來(lái)對(duì)session對(duì)象進(jìn)行相關(guān)操作模型對(duì)象Map類、Model類、ModelMap類都代表模型對(duì)象,可以用于頁(yè)面的數(shù)據(jù)渲染流對(duì)象InputStream類、InputStreamReader類都代表輸入流對(duì)象,可以用來(lái)獲取請(qǐng)求中的數(shù)據(jù);OuputStream類、OuputStreamReader類都代表輸出流對(duì)象,可以用來(lái)輸出響應(yīng)數(shù)據(jù)實(shí)體類對(duì)象項(xiàng)目中的User類、Order類等實(shí)體類都可以作為參數(shù),用來(lái)接收請(qǐng)求中的數(shù)據(jù)控制器方法中處理請(qǐng)求方法除表9-2中的這些參數(shù)外,還支持使用注解來(lái)實(shí)現(xiàn)特定的功能??刂破鞣椒ǖ膮?shù)上常用的注解如表9-3所示。9.4基于注解的SpringMVC框架開(kāi)發(fā)注解類型功能說(shuō)明@PathVariable用于獲取URL地址中的占位符,并綁定到控制器方法的參數(shù)上。例如,請(qǐng)求URL地址中的/user/{id},這個(gè){id}就是URL地址占位符@RequestParam用于獲取HTTP請(qǐng)求參數(shù),并綁定到控制器方法的參數(shù)中@RequestHeader用于獲取HTTP請(qǐng)求消息頭上的數(shù)據(jù),并綁定到控制器方法的參數(shù)中@RequestBody用于獲取HTTP請(qǐng)求體數(shù)據(jù),并綁定到控制器方法的參數(shù)中@CookieValue用于獲取HTTP請(qǐng)求cookie對(duì)象中的數(shù)據(jù),并綁定到控制器方法的參數(shù)中@SessionAttribute用于獲取HTTP請(qǐng)求session對(duì)象中的數(shù)據(jù),并綁定到控制器方法的參數(shù)中以下代碼描述了@PathVariable獲取請(qǐng)求中路徑參數(shù)的方法。9.4基于注解的SpringMVC框架開(kāi)發(fā)//使用http://localhost:8080/springmvc_demo_war_exploded/user/10001.form訪問(wèn)

@RequestMapping(value="/{id}",method=RequestMethod.GET)

publicStringgetUserById(@PathVariableIntegerid){

System.out.println(id);

return"userDetail";

}這時(shí)使用http://localhost:8080/springmvc_demo_war_exploded/user/10001.form

訪問(wèn)這個(gè)方法,在控制器方法中可以獲取從這個(gè)URL地址傳來(lái)的路徑參數(shù)“10001”,然后根據(jù)id獲取用戶。以下代碼描述了使用@RequestParam注解獲取請(qǐng)求中請(qǐng)求參數(shù)的方法。9.4基于注解的SpringMVC框架開(kāi)發(fā)這時(shí)要使用http://localhost:8080/springmvc_demo_war_exploded/user.form?id=1001

訪問(wèn)這個(gè)方法,在控制器方法中可以獲取從這個(gè)URL地址中傳來(lái)的“id=10001”,然后根據(jù)id獲取用戶。//使用http://localhost:8080/springmvc_demo_war_exploded/user.form?id=1001訪問(wèn)

@RequestMapping(method=RequestMethod.GET)

publicStringgetUserById(@RequestParamIntegerid){

System.out.println(id);

return"userDetail";

}9.4.5基于SpringMVC框架的注解開(kāi)發(fā)示例SpringMVC框架支持通過(guò)Java代碼加注解的形式來(lái)創(chuàng)建配置文件,使用方法如下。(1)在src文件夾下的org.example.config包中創(chuàng)建前端控制器配置類DispatcherServletConfig,需要繼承SpringMVC框架提供的一個(gè)AbstractAnnotationConfigDispatcherServletInitializer抽象類。在getRootConfigClasses()方法中添加要加載Spring框架的配置類,在getServletConfigClasses()方法中添加要加載SpringMVC框架的配置類,在getServletMappings()方法中配置前端控制器要攔截的路徑,如例9-8所示。9.4基于注解的SpringMVC框架開(kāi)發(fā)例9-8前端控制器配置類(相當(dāng)于web.xml配置文件)。9.4基于注解的SpringMVC框架開(kāi)發(fā)publicclassDispatcherServletConfigextendsAbstractAnnotationConfigDispatcherServletInitializer{

@Override

protectedClass<?>[]getRootConfigClasses(){

returnnewClass<?>[]{SpringConfig.class};//加載Spring框架的配置類

}

@Override

protectedClass<?>[]getServletConfigClasses(){

returnnewClass<?>[]{SpringmvcConfig.class};//加載SpringMVC框架的配置類

}

@Override

protectedString[]getServletMappings(){

returnnewString[]{"/"};//前端控制器攔截的路徑

}

}例9-8前端控制器配置類(相當(dāng)于web.xml配置文件)。9.4基于注解的SpringMVC框架開(kāi)發(fā)publicclassDispatcherServletConfigextendsAbstractAnnotationConfigDispatcherServletInitializer{

@Override

protectedClass<?>[]getRootConfigClasses(){

returnnewClass<?>[]{SpringConfig.class};//加載Spring框架的配置類

}

@Override

protectedClass<?>[]getServletConfigClasses(){

returnnewClass<?>[]{SpringmvcConfig.class};//加載SpringMVC框架的配置類

}

@Override

protectedString[]getServletMappings(){

returnnewString[]{"/"};//前端控制器攔截的路徑

}

}(2)在src文件夾下的org.example.config包中創(chuàng)建SpringMVC框架的配置類SpringmvcConfig,需要繼承自WebMvcConfigurationSupport類。@Configuration注解表明這是一個(gè)配置類;@ComponentScan注解設(shè)置SpringMVC框架需要掃描的包路徑;@EnableWebMvc注解聲明這是一個(gè)SpringMVC框架的配置類。然后在配置類中配置視圖解析器,并將其裝配到SpringIoC容器中,如例9-9所示。9.4基于注解的SpringMVC框架開(kāi)發(fā)@Configuration

@ComponentScan(basePackages="org.example.controller")

@EnableWebMvc

publicclassSpringmvcConfigextendsWebMvcConfigurationSupport{

@Bean

publicViewResolverviewResolver(){

//配置視圖解析器

InternalResourceViewResolverresolver=newInternalResourceViewResolver();

resolver.setPrefix("/views/");

resolver.setSuffix(".jsp");

resolver.setExposeContextBeansAsAttributes(true);

returnresolver;

}

}(3)在src文件夾下的org.example.config包中創(chuàng)建Spring框架的配置類SpringConfig,這里暫時(shí)無(wú)須對(duì)Spring框架進(jìn)行配置,保持為空即可,如例9-10所示。9.4基于注解的SpringMVC框架開(kāi)發(fā)@Configuration

publicclassSpringConfig{

}(4)上述相關(guān)配置編寫(xiě)完成后,WEB-INF文件夾可以直接刪除??刂破骱鸵晥D的編寫(xiě)同例9-3和例9-4。最終完整的目錄結(jié)構(gòu)如圖9-11所示。9.5.1Model類型的使用Model類型的使用步驟如下。(1)首先使用Model類型作為控制器方法的參數(shù),其次將需要的數(shù)據(jù)添加到model對(duì)象中,如例9-11所示。例9-11在控制器方法中,將需要的數(shù)據(jù)添加到model對(duì)象中。9.5請(qǐng)求處理方法的返回類型@RequestMapping(value="/detail",method=RequestMethod.GET)

publicStringUserDetail(Modelmodel){

Useruser=newUser("張三",18);

//向model對(duì)象中添加數(shù)據(jù),第一個(gè)參數(shù)為key,第二個(gè)參數(shù)為要添加的數(shù)據(jù)

model.addAttribute("user",user);

//返回userDetail.jsp視圖頁(yè)面

return"userDetail";

}(2)在視圖頁(yè)面中通過(guò)${key.屬性}形式獲取model對(duì)象中的數(shù)據(jù),如例9-12所示。由于將user對(duì)象存入model對(duì)象時(shí)設(shè)置的key為“user”,所以${}獲取到的是user對(duì)象的name字段的值,${user.age}獲取到的是user對(duì)象的age字段的值。例9-12在視圖頁(yè)面userDetail.jsp中,獲取model對(duì)象的數(shù)據(jù)。9.5請(qǐng)求處理方法的返回類型<%@pagecontentType="text/html;charset=UTF-8"language="java"isELIgnored="false"%>

<html>

<head>

<title>$Title$</title>

</head>

<body>

<h1>用戶詳情頁(yè)面</h1>

<p>姓名:${user.name}</p>

<p>年齡:${user.age}</p>

</body>

</html>(3)啟動(dòng)項(xiàng)目,用瀏覽器訪問(wèn)Controller類,model對(duì)象的數(shù)據(jù)渲染后返回的視圖頁(yè)面如圖9-12所示。9.5請(qǐng)求處理方法的返回類型圖9-12model對(duì)象的數(shù)據(jù)渲染后返回的視圖頁(yè)面9.5.2ModelAndView類的使用ModelAndView類的使用步驟如下。(1)首先在控制器方法中創(chuàng)建一個(gè)modelAndView對(duì)象,使用setViewName()方法設(shè)置要返回的視圖名稱,使用addObject()方法設(shè)置要返回的模型數(shù)據(jù),如例9-13所示。例9-13在控制器方法中,添加數(shù)據(jù)到modelAndView對(duì)象中,并返回該對(duì)象。9.5請(qǐng)求處理方法的返回類型@RequestMapping(value="/detail2",method=RequestMethod.GET)

publicModelAndViewUserDetail2(){

Useruser=newUser("李四",28);

ModelAndViewmodelAndView=newModelAndView();

//設(shè)置要返回的視圖頁(yè)面名稱

modelAndView.setViewName("userDetail");

//設(shè)置要返回的模型數(shù)據(jù)

modelAndView.addObject("user",user);

returnmodelAndView;

}(2)在視圖頁(yè)面中通過(guò)${key.屬性}形式獲取model對(duì)象中的數(shù)據(jù),同例9-12。(3)啟動(dòng)項(xiàng)目,用瀏覽器訪問(wèn)Controller類,model對(duì)象的數(shù)據(jù)渲染后返回的視圖頁(yè)面如圖9-13所示。9.5請(qǐng)求處理方法的返回類型圖9-13model對(duì)象的數(shù)據(jù)渲染后返回的視圖頁(yè)面9.5.3返回類型為String類型在控制器方法中返回String類型有以下幾種情況。(1)返回的String類型為視圖名稱,這時(shí)SpringMVC框架會(huì)通過(guò)視圖解析器找到視圖頁(yè)面。(2)返回的String類型為Redirect重定向字符串,這時(shí)又分兩種情況:①用“redirect:/user/detail”形式可以重定向到其他控制器方法;②用“redirect:/index.jsp”形式可以重定向到視圖頁(yè)面。9.5請(qǐng)求處理方法的返回類型//重定向到UserController控制器的Detail處理器

@RequestMapping(value="/list",method=RequestMethod.GET)

publicStringuserList(){

return"redirect:/user/detail";

}//重定向到index.jsp視圖頁(yè)面

@RequestMapping(value="/list2",method=RequestMethod.GET)

publicStringuserList2(){

return"redirect:/index.jsp";

}(3)返回的String類型為轉(zhuǎn)發(fā)的forward字符串,例如,“forward:/user/detail”可以轉(zhuǎn)發(fā)到其他控制器方法中,如例9-15所示。例9-15返回的String類型為轉(zhuǎn)發(fā)的forward字符串。9.5請(qǐng)求處理方法的返回類型//轉(zhuǎn)發(fā)到UserController控制器的Detail處理器

@RequestMapping(value="/list3",method=RequestMethod.GET)

publicStringuserList3(){

return"forward:/user/detail";

}轉(zhuǎn)發(fā)和重定向的區(qū)別如下:轉(zhuǎn)發(fā)是Web服務(wù)器的行為,Web服務(wù)器將這個(gè)請(qǐng)求交給其他控制器方法去處理;而重定向是客戶端的行為,Web服務(wù)器告訴瀏覽器還需要再發(fā)起一個(gè)請(qǐng)求,去請(qǐng)求其他的控制器方法。所以轉(zhuǎn)發(fā)時(shí)瀏覽器只發(fā)起了1次請(qǐng)求,而重定向時(shí)瀏覽器發(fā)起了2次請(qǐng)求。9.6.1SpringMVC框架的攔截器使用SpringMVC框架的攔截器(Interceptor)采用AOP的設(shè)計(jì)思想,我們?cè)赟pring框架中曾學(xué)習(xí)到AOP是對(duì)某個(gè)方法的功能增強(qiáng),而攔截器是對(duì)請(qǐng)求處理器方法的功能增強(qiáng)。與Servlet對(duì)象中的過(guò)濾器(Filter)類似,SpringMVC框架的攔截器可以用來(lái)攔截處理器方法,在處理器方法執(zhí)行前后添加一些與主業(yè)務(wù)無(wú)關(guān)的公共功能,如實(shí)現(xiàn)權(quán)限控制、日志記錄、異常記錄、方法執(zhí)行時(shí)間記錄、判斷用戶是否已登錄等功能。通常攔截器類可以通過(guò)兩種方式來(lái)定義:一種是通過(guò)實(shí)現(xiàn)HandlerInterceptor接口或者繼承其子類來(lái)定義;另一種是通過(guò)實(shí)現(xiàn)WebRequestInterceptor接口或繼承其子類來(lái)定義。這兩種接口都一樣提供preHandle()方法、postHandle()方法及afterCompletion()方法。9.6SpringMVC框架的攔截器preHandle()方法會(huì)在控制器方法調(diào)用前執(zhí)行,其返回值表示是否中斷后續(xù)操作。當(dāng)其返回值為true時(shí),表示繼續(xù)向下執(zhí)行;當(dāng)其返回值為false時(shí),會(huì)中斷后續(xù)所有操作(包括調(diào)用下一個(gè)攔截器和控制器類中的方法執(zhí)行等)。postHandle()方法會(huì)在控制器方法調(diào)用后,且解析視圖前執(zhí)行??梢酝ㄟ^(guò)此方法對(duì)請(qǐng)求域中的模型和視圖做進(jìn)一步修改。afterCompletion()方法在整個(gè)請(qǐng)求中完成,即在視圖渲染結(jié)束后執(zhí)行??梢酝ㄟ^(guò)此方法實(shí)現(xiàn)一些資源清理、日志信息記錄等工作。9.6SpringMVC框架的攔截器例9-16演示了攔截器的基本使用方式:定義了一個(gè)攔截器類UserInterceptor,它實(shí)現(xiàn)了HandlerInterceptor接口的preHandle()方法、postHandle()方法及afterCompletion()方法,這里通過(guò)輸出一段話來(lái)表示特定功能已執(zhí)行。攔截器類定義完成后需要到SpringMVC框架的配置文件中配置這個(gè)攔截器,<mvc:interceptors>標(biāo)簽聲明這是一系列攔截器配置內(nèi)容,在該標(biāo)簽內(nèi)可以添加多個(gè)攔截器,每對(duì)<mvc:interceptor>標(biāo)簽代表一個(gè)攔截器配置內(nèi)容。在<mvc:interceptor>標(biāo)簽內(nèi)添加bean標(biāo)簽,在bean標(biāo)簽上使用class屬性定義要使用的攔截器類,SpringMVC框架會(huì)創(chuàng)建該攔截器對(duì)象,并用該攔截器對(duì)象進(jìn)行請(qǐng)求的攔截處理。9.6SpringMVC框架的攔截器9.6SpringMVC框架的攔截器publicclassUserInterceptorimplementsHandlerInterceptor{

@Override

publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{

System.out.println("攔截器preHandle方法...");

returntrue;

}

@Override

publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{

System.out.println("攔截器postHandle方法...");

}

@Override

publicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{

System.out.println("攔截器afterCompletion方法...");

}

}例9-16演示攔截器UserInterceptor的使用,實(shí)現(xiàn)HandlerInterceptor接口。9.6SpringMVC框架的攔截器下面進(jìn)行攔截器的XML配置,在SpringMVC框架的XML配置文件中添加如下配置。<!--配置攔截器-->

<mvc:interceptors>

<mvc:interceptor>

<!--配置攔截器要攔截的路徑-->

<mvc:mappingpath="/**"/>

<!--配置不需要攔截器作用的路徑-->

<mvc:exclude-mappingpath="/login"/>

<beanclass="erceptor.UserInterceptor"/>

</mvc:interceptor>

</mvc:interceptors>啟動(dòng)服務(wù),訪問(wèn)控制器結(jié)果如下。9.6SpringMVC框架的攔截器下面進(jìn)行攔截器的XML配置,在SpringMVC框架的XML配置文件中添加如下配置。<!--配置攔截器-->

<mvc:interceptors>

<mvc:interceptor>

<!--配置攔截器要攔截的路徑-->

<mvc:mappingpath="/**"/>

<!--配置不需要攔截器作用的路徑-->

<mvc:exclude-mappingpath="/login"/>

<beanclass="erceptor.UserInterceptor"/>

</mvc:interceptor>

</mvc:interceptors>啟動(dòng)服務(wù),訪問(wèn)控制器結(jié)果如下。9.6SpringMVC框架的攔截器在例9-16中,在SpringMVC框架的XML配置文件中添加攔截器,同樣也可以在SpringMVC框架的Java配置類上重寫(xiě)addInterceptors()方法來(lái)添加攔截器,代碼如下。@Configuration

@ComponentScan(basePackages="org.example.controller")

@EnableWebMvc

publicclassSpringmvcConfigimplementsWebMvcConfigurer{

@Bean

publicViewResolverviewResolver(){

//配置視圖解析器

InternalResourceViewResolverresolver=newInternalResourceViewResolver();

resolver.setPrefix("/views/");

resolver.setSuffix(".jsp");

resolver.setExposeContextBeansAsAttributes(true);

returnresolver;

}

@Override

publicvoidaddInterceptors(InterceptorRegistryregistry){

//創(chuàng)建攔截器對(duì)象

UserInterceptoruserInterceptor=newUserInterceptor();

//添加一個(gè)攔截器

registry.addInterceptor(userInterceptor).addPathPatterns("/**").

excludePathPatterns("/login");

}

}9.6SpringMVC框架的攔截器9.6.2SpringMVC框架攔截器的執(zhí)行順序有個(gè)最簡(jiǎn)單的情況,在SpringMVC框架中只配置了單個(gè)攔截器。攔截器攔截到請(qǐng)求時(shí)會(huì)在控制器方法調(diào)用前執(zhí)行preHandle()方法,在控制器方法調(diào)用后執(zhí)行postHandle()方法,視圖渲染結(jié)束后執(zhí)行afterCompletion()方法。當(dāng)配置了多個(gè)攔截器時(shí),多個(gè)攔截器的執(zhí)行順序如圖9-14所示。9.6SpringMVC框架的攔截器多個(gè)攔截器的執(zhí)行順序分3個(gè)階段進(jìn)行說(shuō)明,說(shuō)明如下。(1)處理器方法執(zhí)行前。攔截器1的preHandle()方法執(zhí)行→攔截器2的preHandle()方法執(zhí)行→攔截器3的preHandle()方法執(zhí)行。(2)處理器方法執(zhí)行后,視圖渲染前。攔截器3的postHandle()方法執(zhí)行→攔截器2的postHandle()方法執(zhí)行→攔截器1的postHandle()方法執(zhí)行。(3

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論