版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
*/S一種是BS架構(gòu)E/S架構(gòu)B/S架構(gòu)在我們的實(shí)際開發(fā)中使用的非常多,所以我們課程中的案例也都是基于三層架構(gòu)設(shè)計的。也就是我們常說的web層。它負(fù)責(zé)接收客戶端請求,向客戶端響應(yīng)結(jié)果,通??蛻舳耸褂胔ttp協(xié)議請求web層,web需要接收http請求,完成http響應(yīng)。表現(xiàn)層的設(shè)計一般都使用MVC(MVC是表現(xiàn)層的設(shè)計模型,和其他層也就是我們常說的service層。它負(fù)責(zé)業(yè)務(wù)邏輯處理,和我們開發(fā)項(xiàng)目的需求關(guān)。web層依賴業(yè)務(wù)層,但是業(yè)務(wù)層不依賴web層。(也就是我們說的,事務(wù)應(yīng)該放到業(yè)務(wù)層來控制)也就是我們是常說的dao層。負(fù)責(zé)數(shù)據(jù)持久化,包括數(shù)據(jù)層即數(shù)據(jù)庫和數(shù)據(jù)訪問層,數(shù)據(jù)庫是對數(shù)據(jù)進(jìn)行持久化的載體,數(shù)據(jù)層是業(yè)務(wù)層和持久層交互的接口,業(yè)務(wù)層需要通過數(shù)據(jù)層將數(shù)據(jù)持久化到數(shù)據(jù)庫中。通俗的講,持久層就是和數(shù)據(jù)庫交互,對******MVC全名是ModelViewController,是模型(model)view(controller)WebMVC中每個部通常指的就是我們的jsp或者h(yuǎn)tml。作用一般就是展示數(shù)據(jù)的。***SpringMVC是一種基于Java的實(shí)現(xiàn)MVC***SpringMVC是一種基于Java的實(shí)現(xiàn)MVC設(shè)計模型的請求驅(qū)動類型的輕量級框架屬于SpringFrameWork的后續(xù)產(chǎn)品已經(jīng)融合在SpringWebFlow里面Spring框架提供了構(gòu)建Web應(yīng)用程序的全功能MVC模塊使用Spring可 的MVC架構(gòu),從而在使用Spring進(jìn)行WEB開發(fā)時,可以選擇使用Spring的SpringMVC框架或集成其他MVC開發(fā)框架,如Struts1(現(xiàn)在一般不用),Struts2等。***SpringMVC已經(jīng)成為目前最主流的MVC框架之一,并且隨著Spring3.0的發(fā)布,全 Struts2,成為最優(yōu)秀的MVC框架***JavaRESTful請求為什么學(xué)習(xí)也許你要問,為什么要學(xué)習(xí)SpringMVCstruts2嗎?看SSH火其實(shí)很多初學(xué)者了一個概念,SSH實(shí)際上指的是Struts1.x+Spring+Hibernate。這個概念已經(jīng)有Struts1.x霸主,但是在新的MVC時代,形式已經(jīng)不是這樣了,Struts2.x借助了Struts1.x的好名聲,讓國內(nèi)開發(fā)認(rèn)為Struts2.x是霸主繼任者(其實(shí)來了S2SH(Struts2+Spring+Hibernate)整合開發(fā)。不要再被蒙蔽了,的統(tǒng)計吧SpringMVC的市場占有率是40%,而Struts2只有的6%。這已然說明了學(xué)習(xí)SpringMVC的必要性了,再說了,SpringMVC本身就是spring的一員,與整合spring時,SpringMVC根本無需中間整合包,而struts2接下來,讓我們一起看看SpringMVC是如何處理HTTP請求的Modl這不過千萬MVC設(shè)計模式和工程的三層結(jié)構(gòu)三層結(jié)構(gòu)指的是表現(xiàn)層業(yè)務(wù)層數(shù)據(jù)持久層。而MVC計。創(chuàng)建一個mavenwebPOM<project""<project""springioc組件需要的依賴包--><!--基于AspectJ的aop依賴-->springMVC依賴包--><!--jstl--<!--servlet--<!--配置Maven的JDK編譯級別--> MVC中的C在web.xml添加DispatcherServlet置<web-appxmlns:xsi= <!--學(xué)習(xí)前置條件--><!--問題1:web.xml中servelet、filter、listener、context-param<!--問題2:load-on-startup的作用,影響了servlet對象創(chuàng)建的時機(jī)--<!--問題3:url-pattern的配置方式有四種:/dispatcherServlet、/servlet/*、*、/<!--問題4:url-pattern的配置為/*報錯,原因是它了JSP請求,但是又不能處理JSP請<!--問題5:配置了springmvc去spring配置文件之后,就產(chǎn)生了spring父子容器的問題<!--設(shè)置spring配置文件路徑--><!--如果不設(shè)置初始化參數(shù),那么DispatcherServlet會默認(rèn)路徑下的配置文件--<!--默認(rèn)配置文件路徑:/WEB-INF/springmvc-servlet.xml<!--如果不指定初始化時機(jī),DispatcherServlet就會在第一次被請求的時候,才會初始化,而且只會被初始化一次--><servlet-mapURL-PATTERN的設(shè)置--><!--不要配置為/*,否則報錯--><!--通俗解釋:/*,會整個項(xiàng)目中的資源,包含JSP和靜態(tài)資源的,對于靜態(tài)資源的springMVC提供了默認(rèn)的Handler處理器--><!--但是對于JSP來講,springmvc沒有提供默認(rèn)的處理器,我們也沒有手動編寫對于的處理器,此時按照springmvc的處理流程分析得知,它短路了--></servlet-map<!--<servlet>--<!--<servlet-class>sss</servlet-class>--<!--</servlet>--<!--<servlet-map>--<!--</servlet-map>--創(chuàng)建<beans""""MVC中的M接口、注解方式注解方式必要的注解主要有以下兩個pattern配置的是*的話,url中的“”可以加也可以不加。處理器的返回值是ModelAndView一個是將數(shù)據(jù)到Request域中publicclasspublicclassItemController@RequestMappublicModelAndViewqueryItem()throwsException{List<Item>itemList=newArrayList<>();Itemitem_1=newItem();item_1.setDetail("ThinkPadT430聯(lián)想筆Itemitem_2=newItem();item_2.setDetail("6蘋果 //創(chuàng)建modelandViewModelAndViewmodelAndView=new//添加modelmodelAndView.addObject("itemListitemList);return}}注意:商品數(shù)據(jù)使用Item提供的pojopublicclassItem{privateIntegerid;privateStringname;privateFloatprice;privateStringprivateDateprivateString}MVC中的M使用組件掃描器省去在spring置每個controller<!--掃描controller分隔--> <!--掃描controller分隔--> MVC中的V把參考資料中的item-list.jsp到工程的/WEB- 前端控制器前端控制器是如何執(zhí)行對應(yīng)的處理器的1、用戶發(fā)送請求至前端控制器2、DispatcherServlet收到請求調(diào)用HandlerMap處理器器3、處理器器根據(jù)請求url找到具體的處理器,生成處理器對象及處理器器(如果有則生成)一并返4、DispatcherServlet通過HandlerAdapter處理器適配器調(diào)用處理5、HandlerAdapter執(zhí)行處理器(handler6、Controller執(zhí)行完成返回7、HandlerAdapter將handler執(zhí)行結(jié)果ModelAndView返回給9、ViewReslover解析后返回具體View對HandlerMap:處理器是說明:說明:在springmvc的各個組件中,處理 器、處理器適配器、視圖解析器稱為springmvc的三spring-webmvc-xxx.jarspring-webmvc-xxx.jar包中有一個DispatcherSperties該配置中默認(rèn)加載了一些springmvc默認(rèn)的其他組件,其中就包括三大組件。#DefaultimplementationclassesforDispatcherServlet'sstrategy#UsedasfallbackwhennomatchingbeansarefoundintheDispatcherServletcontext.#Notmeanttobecustomizedbyapplicationdevelopers.NameUrlHandlerMap,\org.springframework.web.servlet.mvc.method.annotation.RequestMapHandlerMaporg.springframework.web.servlet.mvc.method.annotation.RequestMap注解器和適配器通過bean配 :注解式處理 對類中標(biāo)記的方法進(jìn)行,根據(jù)定義的url匹配返回HandlerMethodHandlerMethodurlMethod*對標(biāo)記<!--注<!--注 器--<!--注解適配器--><bean 通過mvc配置(推薦<mvc:annotation-drivernHandlerMap<bean<bean<!--該視圖解析器,默認(rèn)的視圖類就是JstlView,可以不寫--><propertyname="viewClass"value="org.springframework.web.servlet.view.JstlView"/>jar包。此屬性可以不設(shè)置,默認(rèn)為JstlViewprefix和suffix:查找視圖頁面的前綴和后綴,最終視圖的址為:前綴+邏輯視圖名+后綴,邏輯視圖名需要在controller中返回的ModelAndView指定,比如邏輯視圖名為o,則最終返回的jsp視圖地址“WEB-INF/jsp/o.jsp”SSM將工程的三層結(jié)構(gòu)中的JavaBean分別使用Spring(XML)進(jìn)行管理1、整合持久層mapper,包括數(shù)據(jù)源、會話工程及mapper對象的整合2、整合業(yè)務(wù)層Service,包括事務(wù)及service的bean3、整合表現(xiàn)層Controller,直接使用springmvc4、Web.xml加載spring(包含多個XMLSpring配置文件依賴包整合第連接工程整合(配置文件整合在classpath下,創(chuàng)建 ,然后創(chuàng)建<?xmlversion="1.0"encoding="UTF-<beansxmlns=xmlns:context=""xmlns:p=xmlns:aop="xmlns:tx="xmlns:xsi=<!--加載perties<context:property-placeholderlocation="classpath:perties"<!--配置數(shù)據(jù)源--> destroy-<propertyname="driverClassName"value="${jdbc.driver}"<propertyname="username"value="${jdbc.username}"<propertyname="password"value="${jdbc.password}"<!--配置SqlSessionFacotory<!--加載mybatis的配置文件(如果配置文件中沒有配置項(xiàng),可以忽略該文件)<propertyname="configLocation"value="classpath:mybatis/SqlMapConfig.xml"<!--配置數(shù)據(jù)源--><propertyname="dataSource"ref="dataSource"<!--配--><bean<!--指定掃描的包--><propertyname="basePackage"value="com.kkb.ssm.mapper"在classpath下,創(chuàng)建 ,然后創(chuàng)建<?xmlversion="1.0"encoding="UTF-8"<!DOCTYPEPUBLIC-////DTDConfig>classpath創(chuàng)建classpath下,創(chuàng)建#devenv[debug]productenvlog4j.rootLogger=DEBUG,stdout#Consoleoutput...log4j.appender.stdout.layout.ConversionPattern=%5p[%t]-%m%n在springapplicationContext-service.xml,文件中配置service需要配置service的bean和事務(wù)管理。<?xmlversion="1.0"encoding="UTF-<beansxmlns=xmlns:context="xmlns:p=xmlns:aop=xmlns:tx="xmlns:xsi=<!--掃描Service ponent-scanbase-package="com.kkb.ssm.service"<!--配置事務(wù)--><!--事務(wù)管理器,對mybatis操作數(shù)據(jù)庫進(jìn)行事務(wù)控制,此處使用jdbc的事務(wù)控制<beanid="transactionManager"<!--指定要進(jìn)行事務(wù)管理的數(shù)據(jù)源--><propertyname="dataSource"<!--通知--><tx:adviceid="txAdvice"transaction-<!--行為--<tx:methodname="save*"propagation="REQUIRED"<tx:methodname="add*"propagation="REQUIRED"<tx:methodname="insert*"propagation="REQUIRED"<tx:methodname="delete*"propagation="REQUIRED"<tx:methodname="del*"propagation="REQUIRED"<tx:methodname="remove*"propagation="REQUIRED"<tx:methodname="update*"propagation="REQUIRED"<tx:methodname="modify*"propagation="REQUIRED"<tx:methodname="query*"read-only="true"<!--aop--<aop:advisoradvice-pointcut="execution(*com.kkb.ssm.service.impl.*.*(..))"整合Spring和springmvcspringmvc配在web.xml添加springmvc<?xmlversion="1.0"encoding="UTF-<web-appxmlns:xsi= xml/ns/javaee"xmlns:web=" id="WebApp_ID"version="2.5"><display-name>ssm</display-<!--配置springmvc的前端控制器--><servlet-name>springmvc</servlet-<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-<init-<param-name>contextConfigLocation</param-<param-value>classpath:spring/springmvc.xml</param-</init-<load-on-startup>1</load-on-<servlet-map<servlet-name>springmvc</servlet-<url-pattern>/</url-</servlet-map</web-在spring包下創(chuàng)建springmvc.xml下<?xmlversion="1.0"encoding="UTF-<beansxmlns=xmlns:xsi="xmlns:p=xmlns:context="xmlns:mvc=<!--配置處理器器和處理器適配器--<mvc:annotation-driven<!--配置視圖解析器--><!--使用注解的handler以使用組件掃描器,加載handler ponent-scanbase-package="com.kkb.ssm.controller"web.xml加載spring在web.xml中,使用器來對spring的配置文件進(jìn)行加載<!--加載spring容器--><context-<param-name>contextConfigLocation</param-<param-classpath:spring/applicationContext-</param-</context-<listener-class>org.springframework.web.context.ContextLoaderListener</listener-整合測試(編寫代碼實(shí)現(xiàn)商品查詢列表,從mysql息請求請求返回值:ModelAndView指定Model和View(item-list.jsp)Request(Model:keyitemList業(yè)務(wù)處理邏輯(需求分析類、和根據(jù)需求開發(fā)service口以及實(shí)現(xiàn)類,注意:使用注解@Service開發(fā)servicepublicclassItemServiceImplimplementsItemServiceprivateItemMapperpublicList<Item>queryItemList()ItemExampleexample=newreturn}}Controller在Controller類上添加@Controller注在Controller方法上添加@RequestMap注解進(jìn)行url請求publicclassItemController{privateItemService@RequestMappublicModelAndViewqueryItem()List<Item>itemList=//創(chuàng)建ModelAndView準(zhǔn)備填充數(shù)據(jù)、設(shè)置視ModelAndViewmodelAndView=new//相當(dāng)于request.setAttribute(key,value)modelAndView.addObject("itemListitemList);//設(shè)置視圖(配置邏輯視圖return}}開發(fā)入門程序中的返回controllerModelAndViewmodelview返回controllerrequestresponserequestresponse,3responsejsonresponse.getWriter().write("json串");返回字符串(推薦returnreturn"item/item-redirectreturnreturnforwardreturnreturn注解和 HttpMessageConverter,匹配不同的Controller返回值類型,然進(jìn)行不同的消息轉(zhuǎn)換處理***將轉(zhuǎn)換之后的數(shù)據(jù)放到HttpServletResponse對象的響應(yīng)體返回到頁面***不同的HttpMessageConverter處理的數(shù)據(jù),指定的ContentType@RequestBody注解的作用和@ResponseBody處理請求參數(shù)的Http消息轉(zhuǎn)換的MapJacksonHttpMessageConverter處理POJO類型返回***JacksonJSONJavaStringHttpMessageConverter處理String類型返回類***調(diào)用response.getWriter()方法將StringURL路徑value的值是數(shù)組,可以將多個url到同一個方窄化請求在class上添加@RequestMap(url)指定通用請求前綴,限制此類下的所有方法的請求url必須以請求前綴開頭,通過此方法對url進(jìn)行模塊化分類管理。GET (method=如果通過Post則報錯HTTPStatus405-Requestmethod'POST'not@RequestMapPOST@RequestMap(method=HTTPStatus405-Requestmethod'GET'notGETPOST@RequestMap都是字符串類型Controller,比如簡單類型、POJO內(nèi)置的后的值賦值給Controller類中方法的形參,這個過程就是參數(shù)綁定。默認(rèn)支持的參數(shù)類型(ServletAPI通過request通過response信通過session對象得到session對ModelMap繼承自LinkedHashMapModel是一個接口,它們的底層實(shí)現(xiàn)都是同一個的作用,Itemitem=Itemitem=簡單類型8String在springmvc對于javahttpkeycontroller形參名稱請求請求參數(shù)的keyControllerController的形參為Integerid,它和請求參數(shù)的key成@RequestMap(value=publicStringfindItem(Integerid){System.out.println("接收到的請求參數(shù)是id);return}請求參數(shù)的key和controller方法的形參名稱不一致時,需要使用請求請求參數(shù)的keyControllerController的形參為Integerid,它和請求的參數(shù)不一致,要使用@RequestParam注解才能綁定成@RequestMap(value=//通過@RequestParam注解綁定簡單類publicStringfindItem(@RequestParam("itemidIntegeridSystem.out.println("接收到的請求參數(shù)是:"+id);return}TTPStatus400-RequiredIntegerparameter'XXXX'isnot@RequestMap(value=/findItem//通過@RequestParam注解綁定簡單類//學(xué)習(xí)@RequestParam注解中的value、required、defaultValue屬publicStringfindItem@RequestParam(value="itemid",required=true,defaultValue="2")Integerid)System.out.println(接收到的請求參數(shù)是id);returnsuccess;}綁定POJO控制器方法的參數(shù)類型是控制器方法的參數(shù)類型是POJO類型。要求表單中參數(shù)名稱和POJO類的屬性名稱請求ControllerController publicStringupdateItem(Integerid,Itemitem)System.out.println("接收到的請求參數(shù)是:"+id);System.out.printlnitem);return"success";}綁定包裝POJOPOJOPOJO一個POJO的這種類,稱之為包裝POJO。publicclassItemQueryVOprivateItem}頁面定義(item-<td>商品名稱:<inputtype="text"name=""<td><inputtype="submit"value="查詢"Controller測試方法:斷點(diǎn),查看vo中的item對象是否有值通過HTTP請求批量傳遞簡單類型數(shù)據(jù)的情況,Controller方法中可以用String[]或者pojo的String[]屬性接收(兩種方式任選其一),但是不能使用集合接收。請求Controller publicStringdeleteitem(Integer[]return}使用POJO必須放在另一個POJO接收商品列表的publicclassItemQueryVO//商品信privateItem//其他信//商品信息集 ist<Item> }請求? x&publicStringbatchUpdateItem(ItemQueryVOvo)return}請求Controller publicStringsaveItem(Stringdate){System.out.println("接收到的請求參數(shù)是date);return"success";}但是如果將date參數(shù)的類型由StringDate自定義publicpublicclassDateConverterimplementsConverter<String,Date>publicDateconvert(Stringsource)tryreturn}catch(ParseExceptione){}return}}配置在springmvc.xml置<!--加載注解<!--加載注解驅(qū)動--><!--轉(zhuǎn)換器配置--><property<bean<bean注解的類進(jìn)行增強(qiáng)。***該注解使用 注解,這樣的話當(dāng)我們使<注應(yīng)用到所有的Controller類中publicclassMyControllerAdvicepublicMap<String,Object>Map<String,Object>map=newHashMap<>();map.put("name","tom");return}publicvoidinitBinder(WebDataBinderdataBinder)}publicStringhandleException(Exceptione)return}}作用于方法(有沒有注解的方法都可以*非執(zhí)行時機(jī):在本類內(nèi)所有作用*ModelMap*有*返回值會放入ModelMap中么這個URL作用于方法參數(shù)(有注解的方法方法產(chǎn)生***STEP2ModelMap***如果STEP1STEP2ModelMapkey******由@InitBinder標(biāo)識的方法,可以通過PropertyEditor解決數(shù)***不過PropertyEditor只能完成String-->任意類型ConverterConverter任意類型-->任意類型***它可以對WebDataBinder對象進(jìn)行初始化,WebDataBinder是DataBinderDataBinder的子類,用于完成由表單字段到JavaBean屬性的綁定。***注意事項(xiàng):**方法為void@InitBinder參數(shù)通常是WebDataBinder******這個注解表示Controller的方法springmvc在處理請求過程中出現(xiàn)異常信息交由異常處理器進(jìn)行處理,自定義異常處理器異常包含編譯時異常和運(yùn)行時異常,其中編譯時異常也叫預(yù)期異常常,必須使用trycatch代碼塊或者throws關(guān)鍵字來處理異常。系統(tǒng)的dao、service、controller出現(xiàn)都通過throwsException publicclasspublicclassBusinessExceptionextendsExceptionprivateStringpublicBusinessException(Stringmessage)this.message=message;}}publicStringgetMessage()return}publicvoidsetMessage(Stringmessage)this.message=}}publicpublicclassBusinessExceptionResolverimplementsHandlerExceptionResolverpublicModelAndViewresolveException(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex){BusinessExceptionbusinessException=if(exinstanceofBusinessException){businessException=(BusinessException)ex;businessExceptionnewBusinessException}ModelAndViewmodelAndView=newreturnmodelAndView;}}<%@<%@pagelanguage="java"contentType="text/html;charset=UTFEncoding="UTF-<!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN" <metahttp-equiv="Content-Type"content="text/html;charset=UTF-${message在springmvc.xml<!--自定義異常處理器(全局)<!--自定義異常處理器(全局)--><bean (value=publicStringshowItemEdit(Integerid,Modelmodel)throws//查詢要顯示的商品內(nèi)Itemitem=if(itemnullthrownewBusinessException("查詢不到商品無法修改");model.addAttribute("item",item);//由于配置了//由于配置了}上傳SpringMVCcommons-fileuploadjar文件上傳需要指定enctype=”multipart/form-配置Multipartmultipart<beanmultipart<bean ><!--上傳文件的最大尺寸5M<propertyname="maxUploadSize"上傳代Controllerifif(pictureFile!= StringoriginalFilename= if(originalFilename!=null&&{//存 StringpicPath="E:\\03-teach\\07-StringnewFileName=FilenewFile=new (value=publicStringupdateItem(Modelmodel,ItemMultipartFilepictureFile)throwsExceptionthrownewBusinessException("名稱不存在,上傳不成功}}return}Jsp<td>商 <c:iftest="${item.pic<inputtype="file"配置文件的虛注意:在虛擬 中,一定將分級創(chuàng)建(提高i/o性能一般我們采用按日eclipse配置tomcat直接修改tomcat在tomcat安 為什么使用JSONJSONHTMLAjaxJSON請求是KV,響應(yīng)是JSON(推薦使用JSON輸入key/valueJSON(推薦JSPfunctionfunctionontextPath}}Controller//輸入是//輸入是key/value,輸出是//@ResponseBody將返回值轉(zhuǎn)成json串響應(yīng)給前臺 publicItemresponseKV(Itemitem)return}輸入JSON、輸出JSPfunctionontextPath//輸入是json是,需要指定contentType為}}functionontextPath//輸入是json是,需要指定contentType為}}ControllerpublicclassJsonController//輸入是json,輸出是@RequestBody將請求的json串轉(zhuǎn)成java@ResponseBody將返回值轉(zhuǎn)成json publicItemrequestJson(@RequestBodyItemitem)returnreturn}}什么是mock對象對象mockServlet、Request、ResponseServletAPIServlet***這個虛擬的對象mock***mock就是真實(shí)對象在調(diào)試期間的代替品為什么使用mock基于RESTfulSpringMVCSpringMVC程,即從URL請求到控制器處理,再到視圖渲染都可以測試。MockMvcBuilderMockMvc其主要有兩個實(shí)現(xiàn): 對于我們來說直接使用靜態(tài)工廠MockMvcBuildersstandaloneSetup(Object...器并得到相應(yīng)的MockMvc對于服務(wù)器端的SpringMVC測試支持主點(diǎn)由方法:perform(RequestBuilderrb)執(zhí)行一個RequestBuilder請求,會自動執(zhí)行SpringMVC的流程并到相應(yīng)的控制器執(zhí)行處理,該方法的返回值是一個ResultActions;其主要有兩個子類MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder(如文件上傳使用,即用來Mock客戶端請求需要的所有數(shù)據(jù)。用來匹配執(zhí)行完請求后的包含了很多驗(yàn)證API比如此處使用MockMvcResultHandlers.print單元測試執(zhí)行結(jié)果,可以針對執(zhí)行結(jié)果進(jìn)行自定義驗(yàn)證邏輯spring單元測試組件包--><!--單元測試JunitMock測試使用的json-path依賴-->importstaticorg.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;importstaticorg.springframework.test.web.servlet.result.MockMvcResultHandlers.print;importstaticorg.springframework.test.web.servlet.result.MockMvcResultMatchers.status;importstaticorg.springframework.test.web.servlet.result.MockMvcResultMatchers.content;importimportimportimportimportimportimportorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;importorg.springframework.test.context.web.WebAppConfiguration;importorg.springframework.test.web.servlet.MockMvc;importimportorg.springframework.test.web.servlet.request.MockMvcRequestBuilders;importorg.springframework.test.web.servlet.result.MockMvcResultHandlers;importorg.springframework.test.web.servlet.result.MockMvcResultMatchers;importorg.springframework.test.web.servlet.setup.MockMvcBuilders;import@ContextConfiguration(locations="classpath:spring/*.xml")publicclassTestMockMVCprivateWebApplicationContextprivateMockMvcmockMvc;publicvoidsetup()//初始化一個MockMVC對象的方式有兩種:單獨(dú)設(shè)置、web//建議使用Web應(yīng)用上下文設(shè)mockMvc=}publicvoidtest()throwsException//通過perform去發(fā)送一個HTTP請//andDoMvcResultresult=}publicvoidtest2()throwsException//通過perform去發(fā)送一個HTTP請//andDoMvcResultresult=mockMvc.perform(get("/item/findItem").param("id", .andExpect(jsonPath("$.name").value("臺式機(jī)}}用于一個ApplicationContext集成測試加載WebApplicationContext理解什么是REST之前,先去理解一下什么是HTTP,參考【HTTP,簡稱(源表述性狀態(tài)轉(zhuǎn)化描述了一個架構(gòu)樣式的網(wǎng)絡(luò)系統(tǒng),比如web應(yīng)用程序。***價值在于如何設(shè)計出符合REST風(fēng)格的******REST指的是一組架構(gòu)約束條件和原則。滿足這些約束條件和原則的應(yīng)用程序或設(shè)計就是RESTful。((Resources可以用一個URI(統(tǒng)一資源定位符)指向它,每種資源對應(yīng)一個特定的URI它的URI就可以,因此URI(eresetation(RepresentationtxtHTML式、XML格式、JSON格式表現(xiàn),甚至可以采用二進(jìn)制格式。ransferransfer是“表現(xiàn)層狀態(tài)轉(zhuǎn)化”。具體說,就是HTTP協(xié)議里面,四個表示操作方用來獲取資源,POST用來新建資源,PUT用來更新資源,DELETE用來刪除動詞設(shè)計:也就是針對資源的具體操作類型,由動詞設(shè)計:也就是針對資源的具體操作類型,由HTTPHTTPPOST、DELETE、PUT、RESTful的示例:/account/1HTTP/account/1HTTPGET:得到id=1的/account/1HTTPDELETE:刪除id=1的/account/1HTTP 更新id1的RESTful的URL RESTful請求 queryItemById(@PathVariable RESTful的@RequestMap:通過設(shè)置method屬性的CRUD,可以將同一URL到不同的HandlerMethod方法@GetMap、@PostMap、@PutMap、@DeleteMap注解同@RequestMap注解的method屬性RESTfulRESTful服務(wù)中一個重要的特性就是一種資源可以有式式,在中可以使用擴(kuò)展名,比如.jsonJSONxmlXML據(jù)請求頭設(shè)置Accept,比如設(shè)置Accept為application/json協(xié)商管理器,直接使用@ResponseBody注解將數(shù)據(jù)按照J(rèn)SON靜態(tài)資源如果在DispatcherServlet中設(shè)置url-pattern為/則必須對靜態(tài)資源進(jìn)行處理<!--當(dāng)DispatcherServlet配置為/ <!--當(dāng)DispatcherServlet配置為/ <mvc:resourceslocation="/css/" mapResourceHttpRequestHandler,這樣靜態(tài)資源在經(jīng)過DispatcherServlet轉(zhuǎn)發(fā)時就可以找到對應(yīng)的Handler了。15SpringMVC的器主要是針對特定處理器進(jìn)行的SpringMVC器介業(yè)務(wù)處理,類似與servletFilterSpringMVC中的請求是通過HandlerInterceptorSpringMVC中定義一個Interceptor4SpringHandlerInterceptor繼承實(shí)現(xiàn)了HandlerInterceptorSpring已經(jīng)提供的實(shí)現(xiàn)HandlerInterceptor接口的抽象類HandlerInterceptorAdapter;3)實(shí)現(xiàn)Spring的WebRequestInterceptor接口;4)繼承實(shí)現(xiàn)了WebRequestInterceptor定義publicclasspublicclassMyHandlerIntercepter1implementspublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{return}publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{}publicvoid pletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{}}配置器是綁定在,則該中的,即;如果某個成功的針對單個HandlerMap配只有通過該處理器器查找到的處理器,才能使用該器<property<refbean="interceptor"<beanid="interceptor"class="erceptor.MyHandlerInterceptor"<<property<refbean="interceptor"<beanid="interceptor"class="erceptor.MyHandlerInterceptor"<全局器配置(推薦SpringMVC的全局器配置,其實(shí)是把配置的器注入到每個已初始化<!--配置全局 <!--配置全局 器--<!--公 所有請求,而且可以有多個--<beanclass="erceptor.MyHandlerInterceptor1"<beanclass="erceptor.MyHandlerInterceptor2"<!--如果有多 器,則按照順序進(jìn)行配置--<!--/**表示所有 URL路徑-- path="/test/**"<!--特定請求 器只能有一個--<beanclass="erceptor.MyHandlerInterceptor3"多器規(guī)器應(yīng)用(實(shí)現(xiàn)登錄認(rèn)證器對的請求URL進(jìn)行校1、如果請求的URL是公開地址(無需登錄就可以的URL,具體指的就是保護(hù)login字段的請求URL,采取放行。2session3session登錄jsp<%@<%@pagelanguage="java"contentType="text/html;charset=UTFEncoding="UTF-<!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN" <metahttp-equiv="Content-Type"content="text/html;charset=UTF-<form " <td><inputtype="submit"value=ControllerpublicclassLoginController publicStringreturn}//登 publicStringlogin(HttpSessionsession,Stringusername,Stringpassword)//Service進(jìn)行用 //把用戶信息保存到session//重定向到商品列表頁return}//退 publicpublicStringlogout(HttpSessionsession)return}}類publicclassLoginInterceptorimplementsHandlerInterceptorpublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{//獲取請求的StringrequestURI= 1、如果請求的URL是公開地址(無需登錄就可 2、如果用戶session存在,則放行Stringusername=(String)if(username!=null&&!username.equals(""))return 3、如果用戶sessionreturn}publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{//TODOAuto-generatedmethod}}publicHttpServletResponseresponse,Objecthandler,ExceptionthrowsException//TODOAuto-generatedmethod}}<!--<!--配置全局 <!--如果有多個器-->器,則按照順序進(jìn)行配置--><!--/**表示所有 URL路徑-- path="/**"<beanclass="erceptor.LoginInterceptor"<!--如果有多 器,則按照順序進(jìn)行配置--<!--/**表示所有 URL路徑-- path="/**"<beanclass="erceptor.MyHandlerInterceptor"問題1:在子容器一個Bean,然后父容器中使用@Autowired注解注入,問題2@Autowired注解的開啟方式有哪些?如果父容器中不開啟******由于瀏覽器對于Javascript的同源策略的限制,導(dǎo)致不能通過(Ajax)B***跨域指的是/hh程序,他利用IFrame他的頁面上,當(dāng)你使用真實(shí)的用戶名,登錄時,他的頁面就可以通過到你的表單中input***解決跨域的方式有多種,比如***解決跨域的方式有多種,比如基于JavaScript的解決方式、基于的JSONP、以及基于CORS***JSONP和CORSJSONP只能解決get、CORS支持GET方式,同時也支持POST提交方式。***我們重點(diǎn)就來講解CORS什么是******CORSW3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-originresourcesharing***它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequestAJAX***CORS瀏覽器和服務(wù)器同時支持瀏覽器不能低于IE10OriginheaderAccess-Control-Allow-Origin,則瀏覽器將CORS請求分成兩類:簡單請求(simplerequest)和非簡單請request只要同時滿足以下兩大條件,就屬于簡單請求加一個Origin字段。該字段是必須的。它的值要么是請求時Origin字段的值,要么是一個*不,******非簡單請求是那種對服務(wù)器有特殊要求的請求,比如請求方法是PUTDELETEDELETE,或者Content-Type字段的類型是application/json(prefligt***出正式的XMLHttpRequest樣請求。下面是這個"預(yù)檢"請求的HTTP頭信息。"預(yù)檢"請求用的請求方法是"預(yù)檢"請求用的請求方法是字段是除了CORS是X-Custom-Header。CORS,OriginAccess-Control-Allow-Origin使用使用springmvc 器實(shí)publicclassAllowOriginInterceptorimplementsHandlerInterceptorpublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,ObjectthrowsException//有跨域行為時參考 if(request.getHeader("Origin")!=null){//允許哪一個//允許那種請求方response.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS, System.out.println("正在}return}}配置器的代碼,請自行補(bǔ)充***Access-Control-Allow-Credentials為true的時候,Access-Control-Allow-Origin*”,否則報錯***如果有多 器,一定要把處理跨域請求 器放到首位JSJqueryurl:'自己要請求的method:'請求方式',//GETPOSTPUT}全局在模塊配置中添加 }$http.get(url,{withCredentials:$http.post(url,data,{withCredentials:publicclassAllowOriginInterceptorimplementsHandlerInterceptorpublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,ObjectthrowsException//有跨域行為時參考 if(request.getHeader("Origin")!=null){//允許哪一個URLrequest.getHeader("Origin")根據(jù)請求來的url動態(tài)允//允許那種請求方response.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE,HEAD");response.setHeader("Access-Control-Max-Age","0");//允許請求頭里的參數(shù)列response.setHeader("Access-Control-Allow-"Origin,No-Cache,X-Requested-With,If-Modified-Since,Pragma,Last-Modified,Cache-Control,Expires,Content-Type,X-E4M-With,userId,token");//允許對方response.setHeader("XRequestAllowed","1");System.out.println("正在}return}}Servletservice:Servlet對象被HTTP請求時調(diào)DispatcherServletSpring有兩種Bean的初始化(不是實(shí)例化)方式***一種是實(shí)現(xiàn)InitializingBean接***一種是通過反射調(diào)用bean ***不同點(diǎn):接口比配置效率高,但是配置消除了對spring依InitializingBean接口為bean***afterPropertiesSet***凡是實(shí)現(xiàn)該接口的類,在初始化bean實(shí)現(xiàn)InitializingBeaninit-method***系統(tǒng)afterPropertiesSet這種BeanSpring***執(zhí)行時機(jī):在創(chuàng)建Bean (AutowireCapableBeanFactoryinvokeInitMethods主流程初始化:GenericServlet(實(shí)現(xiàn)了Servlet接口)的接下來準(zhǔn)備調(diào)用GenericServlet的init而是被子類HttpServletBean給覆蓋了,我們直接看看的init(接下來調(diào)用initServletBean(),不過該方法需要去HttpServletBean的子類FrameworkServlet中去看看方法調(diào)用到這里,我們終于知道DispatcherServlet下來我們?nèi)タ纯碏rameworkServlet類的initWebApplicationContext方法557springmvc.xmlspringonRefresh()方法是初始化一些默認(rèn)組件,比如HandlerMap組件中,看到了這個地方,大家已經(jīng)明白入門程序?yàn)槭裁礇]有配置三大組件,們隨便找個initHandlerMap來了解一下它們是怎么實(shí)現(xiàn)的吧看看是如何加載默認(rèn)策略的,進(jìn)入getDefaultStrategies那么defaultStrategies至此,DispatcherServlet:HttpServletservice(request參數(shù)不是Http繼續(xù)到另一個service方(請求和響應(yīng)都是HTTP開頭該方法根據(jù)請求的method分別調(diào)用相應(yīng)的處理。那接下來我們應(yīng)該去看看doGet和doPost方法是如何處理請求的?但是問題是我們應(yīng)該看哪個類中的doGet和doPost方法呢?通過上面的繼承體系分析得知,我們應(yīng)該去FrameworkServlet類看看到現(xiàn)在為止,我們還沒有進(jìn)入到我們的DispatcherServlet續(xù)去processRequest方法看一下通過這個doService方法才正式進(jìn)入到DispatcherServlet至此,我們終于找到了DispatcherServlet中最的一個方法源碼閱讀到這里,最起碼從主流程中我們可以得知DispatcherServlet何處理一個請求的了。但是我們看到現(xiàn)在,還沒有看出來DispatcherServlet大組件與DispatcherServlet交互的地方。處理器器與DispatcherServlet交互的代碼:getHandler方處理器適配器與DispatcherServlet交互的代碼:getHandlerAdapter方視圖解析器與DispatcherServlet入processDispatchResult方法再進(jìn)入render這個resolveViewName方法就是視圖解析器和DispatcherServlet到此,DispatcherServlet的主流程以及三大組件和它的們都已經(jīng)處理器 的afterPropertiesSetafterPropertiesSet看,其中又調(diào)用了intitHandlerMethods方法(程我們繼續(xù)去看看detectHandlerMethods方法處理方法 Method和 Info的關(guān) 關(guān)系 Info與URL和HandlerMethod的關(guān)系我們先看第一大步驟,也就是調(diào)用MethodIntrospector.selectMethods方我們?nèi)タ匆? 類實(shí)現(xiàn)中調(diào)用 至此第一大步驟我們閱讀完了,接下來去看看第二大步驟,我們看看類的registerHandlerMethod接下來,我們?nèi)タ纯磖egister方法至此處理至此處理 分析:DispatcherServlet類中的getHandler方接下來我們需要進(jìn)入到具體 HandlerMap去執(zhí)getHandlergetHandlerInternalHandlerMethodMap類去實(shí)現(xiàn)的接下來我們重點(diǎn)去看看lookupHandlerMethod方法(方法我們繼續(xù)去看看addMatchingMaps方 RequestMapInfoHandlerMap getMatchingMap方最后去RequestMapInfo類去看看getMatchingCondition方分析源碼:DispatcherServlet的doDispatcher方流程分析類流程分析類流程分析類分析源 :RequestMap以上方法,分別了處理器增強(qiáng)類的相關(guān)操作(@ModelAttribute、@EcetioHaler這些的參數(shù)解析器和返回值處理器會在執(zhí)行Handler方法時進(jìn)行調(diào)用分析源 接著進(jìn) pter類的Handle方進(jìn)入RequestMapHandlerAdapter類執(zhí)行handleInternal方進(jìn)入invokeHandlerMethodServletInvocableHandlerMethod類的invokeAndHandle分析:InvocableHandlerMethod類的invokeForRequest方進(jìn)入getMethodArgumentValues posite此處需要根據(jù)具體參數(shù)類型調(diào)用相應(yīng)的解析器,其中簡單類型NamedValueMethodArgumentResolver類中的方法;POJO類型調(diào)用的都是ModelAttributeMethodProcessor類中的方法我們就 我們進(jìn) 類中及它們處理參數(shù)轉(zhuǎn)換的區(qū)別就行了。下面的代碼是在分析:ServletInvocableHandlerMethod類的invokeAndHandle方返回值由this.returnValueHandlers進(jìn)行處理,這個成員變量的類型是 posite,它繼承自HandlerMethodReturnValueHandler類,該類有兩個方法: 如果返回值使用@ResponseBody注解,那么由它注解的返回值會使用進(jìn) 方法,這個方法MessageConverterMethodProcessor類中,而且這個方法的繼續(xù)深 GenericHttpMessageConverter類的write方分析:DispatcherServlet類的1008行代進(jìn)入processDispatchResult我們此時注意目的是為了解決視圖解析,所以進(jìn)入render進(jìn)入resolveViewName接下來進(jìn) posite類的resolveViewName方接下來進(jìn) 進(jìn)入UrlBasedViewResolvercreateViewUrlBasedViewResolver類的buildViewdrivern//第二種Handler處理器的編寫方式:實(shí)現(xiàn)HttpRequestHandler接publicclassItemController2implementsHttpRequestHandlerthrowsServletException,IOException{List<Item>itemList=newArrayList<Item>();Itemitem_1=newItem();item_1.setName想筆記本);item_1.setDetail(ThinkPadT430聯(lián)想筆記本電腦!);Itemitem_2=newItem();item_2.setName(蘋果);item_2.setDetail(6蘋果!);//數(shù)據(jù)request.setAttribute(itemList,request.getRequestDispatcher(/WEB-INF/jsp/item/item-list.jsp).forward(request,}}實(shí)現(xiàn)Controller開發(fā)時需要實(shí)現(xiàn)Controller//第式:實(shí)現(xiàn)Controller接publicclassItemControllerimplementsController{publicModelAndViewhandleRequest(HttpServletRequestreq,HttpServletResponseresp)throwsException{//TODOAuto-generatedmethodstubList<Item>itemList=newArrayList<Item>();Itemitem_1=newItem();item_1.setName想筆記本);item_1.setDetail(ThinkPadT430聯(lián)想筆記本電腦!);Itemitem_2=newItem();item_2.setName(蘋果);item_2.setDetail(6蘋果!);//創(chuàng)建ModelAndView準(zhǔn)備填充數(shù)據(jù)、設(shè)置視ModelAndViewmodelAndView=new//相當(dāng)于modelAndView.addObject(itemList,//指定視圖的地modelAndView.setViewName(WEB-INF/jsp/item/itemList.jspreturn}}Handler<!--配置處理器--><bean非注解方式的處理器器和適配如果在DispatcherSperties器器之BeanNameUrlHandlerMap:*將的name*這樣就可以通過getBean(url 配置Handler和url關(guān)根據(jù)器的規(guī)則,在springmvc.xml中配置URL和處理器beanname之間的關(guān)<!--配置處理器--><beanname="/queryItem"請求處理器適配器通過supports方法適配所有實(shí)現(xiàn)了HttpRequestHandler器通過handle該適配器只能適配執(zhí)行實(shí)現(xiàn)了HttpRequestHandler接口的handlerpublicclassItemController1implementsHttpRequestHandlerpublicvoidhandleRequest(HttpServletRequest//此處省}}顯式配置:在springmvc.xml<!--配置http請求處理器適配器--><beanpublicbooleansupports(Objecthandler)return(handlerinstanceof}throwsException((HttpRequestHandler)handler).handleRequest(request,return}}適配器之通過supportsController通過handle開發(fā)Handler實(shí)現(xiàn)Controller//springmvc的handler開發(fā)要實(shí)現(xiàn)Controller接口(除了實(shí)現(xiàn)Co
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度海洋牧場建筑工程種類合同
- 2025年度夫妻共同財產(chǎn)捐贈協(xié)議
- 2025年度交通設(shè)施工程監(jiān)理合同范本
- 2025年度農(nóng)產(chǎn)品供應(yīng)鏈管理服務(wù)合同
- 2025年度救護(hù)車跨區(qū)域緊急派遣合作協(xié)議
- 2025年度跨境數(shù)據(jù)傳輸合同內(nèi)容與數(shù)據(jù)安全保護(hù)
- 2025年度股權(quán)質(zhì)押貸款合同范本(針對高新技術(shù)項(xiàng)目)
- 二零二五年度農(nóng)產(chǎn)品加工企業(yè)技術(shù)改造合作合同
- 2025年中國金屬復(fù)合材料行業(yè)市場集中度、市場規(guī)模及未來前景分析報告
- 甲基四氫苯酐品牌在商業(yè)環(huán)境中的品牌忠誠度提升
- 暢捷通g6財務(wù)管理系統(tǒng)專業(yè)版使用手冊
- 化工儀表及自動化ppt課件匯總?cè)譸pt完整版課件最全教學(xué)教程整套課件全書電子教案全套電子講義
- 2022注冊電氣工程師專業(yè)考試規(guī)范清單匯總
- 一年級寫字下學(xué)期課件(PPT 38頁)
- 桂花-作文ppt-PPT課件(共14張)
- 高一數(shù)學(xué)概率部分知識點(diǎn)總結(jié)及典型例題解析 新課標(biāo) 人教版 必修
- 鐵路運(yùn)費(fèi)計算方法
- 《小腦梗死護(hù)理查房》
- 免疫及炎癥相關(guān)信號通路
- 某風(fēng)電場設(shè)備材料設(shè)備清單
- —橋梁專業(yè)施工圖設(shè)計審查要(終)
評論
0/150
提交評論