`
黄继华
  • 浏览: 43402 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

spring与其它框架集成

 
阅读更多
  1. Chapter14.Integratingwithotherwebframeworks
  2. 14.1.Introduction
  3. SpringcanbeeasilyintegratedintoanyJava-basedwebframework.AllyouneedtodoistodeclaretheContextLoaderListenerinyourweb.xmlanduseacontextConfigLocation<context-param>tosetwhichcontextfilestoload.
  4. The<context-param>:
  5. <context-param>
  6. <param-name>contextConfigLocation</param-name>
  7. <param-value>/WEB-INF/applicationContext*.xml</param-value>
  8. </context-param>
  9. The<listener>:
  10. <listener>
  11. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  12. </listener>
  13. NOTE:ListenerswereaddedtotheServletAPIinversion2.3.IfyouhaveaServlet2.2container,youcanusetheContextLoaderServlettoachievethissamefunctionality.
  14. Ifyoudon'tspecifythecontextConfigLocationcontextparameter,theContextLoaderListenerwilllookfora/WEB-INF/applicationContext.xmlfiletoload.Oncethecontextfilesareloaded,SpringcreatesaWebApplicationContextobjectbasedonthebeandefinitionsandputsitintotheServletContext.
  15. AllJavawebframeworksarebuiltontopoftheServletAPI,soyoucanusethefollowingcodetogettheApplicationContextthatSpringcreated.
  16. WebApplicationContextctx=WebApplicationContextUtils.getWebApplicationContext(servletContext);
  17. TheWebApplicationContextUtilsclassisforconvenience,soyoudon'thavetorememberthenameoftheServletContextattribute.ItsgetWebApplicationContext()methodwillreturnnullifanobjectdoesn'texistundertheWebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTEkey.RatherthanriskgettingNullPointerExceptionsinyourapplication,it'sbettertousethegetRequiredWebApplicationContext()method.ThismethodthrowsanExceptionwhentheApplicationContextismissing.
  18. OnceyouhaveareferencetotheWebApplicationContext,youcanretrievebeansbytheirnameortype.Mostdevelopersretrievebeansbyname,thencastthemtooneoftheirimplementedinterfaces.
  19. Fortunately,mostoftheframeworksinthissectionhavesimplerwaysoflookingupbeans.NotonlydotheymakeiteasytogetbeansfromtheBeanFactory,buttheyalsoallowyoutousedependencyinjectionontheircontrollers.Eachframeworksectionhasmoredetailonitsspecificintegrationstrategies.
  20. 14.2.JavaServerFaces
  21. JavaServerFaces(JSF)isacomponent-based,event-drivenwebframework.AccordingtoSunMicrosystem'sJSFOverview,JSFtechnologyincludes:
  22. AsetofAPIsforrepresentingUIcomponentsandmanagingtheirstate,handlingeventsandinputvalidation,definingpagenavigation,andsupportinginternationalizationandaccessibility.
  23. AJavaServerPages(JSP)customtaglibraryforexpressingaJavaServerFacesinterfacewithinaJSPpage.
  24. 14.2.1.DelegatingVariableResolver
  25. TheeasiestwaytointegrateyourSpringmiddle-tierwithyourJSFweblayeristousetheDelegatingVariableResolverclass.Toconfigurethisvariableresolverinyourapplication,you'llneedtoedityourfaces-context.xml.Aftertheopening<faces-config>element,addan<application>elementanda<variable-resolver>elementwithinit.ThevalueofthevariableresolvershouldreferenceSpring'sDelegatingVariableResolver:
  26. <faces-config>
  27. <application>
  28. <variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
  29. <locale-config>
  30. <default-locale>en</default-locale>
  31. <supported-locale>en</supported-locale>
  32. <supported-locale>es</supported-locale>
  33. </locale-config>
  34. <message-bundle>messages</message-bundle>
  35. </application>
  36. ByspecifyingSpring'svariableresolver,youcanconfigureSpringbeansasmanagedpropertiesofyourmanagedbeans.TheDelegatingVariableResolverwillfirstdelegatevaluelookupstothedefaultresolveroftheunderlyingJSFimplementation,andthentoSpring'srootWebApplicationContext.ThisallowsyoutoeasilyinjectdependenciesintoyourJSF-managedbeans.
  37. Managedbeansaredefinedinyourfaces-config.xmlfile.Belowisanexamplewhere#{userManager}isabeanthat'sretrievedfromSpring'sBeanFactory.
  38. <managed-bean>
  39. <managed-bean-name>userList</managed-bean-name>
  40. <managed-bean-class>com.whatever.jsf.UserList</managed-bean-class>
  41. <managed-bean-scope>request</managed-bean-scope>
  42. <managed-property>
  43. <property-name>userManager</property-name>
  44. <value>#{userManager}</value>
  45. </managed-property>
  46. </managed-bean>
  47. TheDelegatingVariableResolveristherecommendedstrategyforintegratingJSFandSpring.Ifyou'relookingformorerobustintegrationfeatures,youmighttakealookattheJSF-Springproject.
  48. 14.2.2.FacesContextUtils
  49. AcustomVariableResolverworkswellwhenmappingyourpropertiestobeansinfaces-config.xml,butattimesyoumayneedtogrababeanexplicitly.TheFacesContextUtilsclassmakesthiseasy.It'ssimilartoWebApplicationContextUtils,exceptthatittakesaFacesContextparameterratherthanaServletContextparameter.
  50. ApplicationContextctx=FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
  51. 14.3.Struts
  52. StrutsisthedefactowebframeworkforJavaapplications,mainlybecauseitwasoneofthefirsttobereleased(June2001).InventedbyCraigMcClanahan,StrutsisanopensourceprojecthostedbytheApacheSoftwareFoundation.Atthetime,itgreatlysimplifiedtheJSP/Servletprogrammingparadigmandwonovermanydeveloperswhowereusingproprietaryframeworks.Itsimplifiedtheprogrammingmodel,itwasopensource,andithadalargecommunity,whichallowedtheprojecttogrowandbecomepopularamongJavawebdevelopers.
  53. TointegrateyourStrutsapplicationwithSpring,youhavetwooptions:
  54. ConfigureSpringtomanageyourActionsasbeans,usingtheContextLoaderPlugin,andsettheirdependenciesinaSpringcontextfile.
  55. SubclassSpring'sActionSupportclassesandgrabyourSpring-managedbeansexplicitlyusingagetWebApplicationContext()method.
  56. 14.3.1.ContextLoaderPlugin
  57. TheContextLoaderPluginisaStruts1.1+plug-inthatloadsaSpringcontextfilefortheStrutsActionServlet.ThiscontextreferstotherootWebApplicationContext(loadedbytheContextLoaderListener)asitsparent.Thedefaultnameofthecontextfileisthenameofthemappedservlet,plus-servlet.xml.IfActionServletisdefinedinweb.xmlas<servlet-name>action</servlet-name>,thedefaultis/WEB-INF/action-servlet.xml.
  58. Toconfigurethisplug-in,addthefollowingXMLtotheplug-inssectionnearthebottomofyourstruts-config.xmlfile:
  59. <plug-inclassName="org.springframework.web.struts.ContextLoaderPlugIn"/>
  60. Thelocationofthecontextconfigurationfilescanbecustomizedusingthe"contextConfigLocation"property.
  61. <plug-inclassName="org.springframework.web.struts.ContextLoaderPlugIn">
  62. <set-propertyproperty="contextConfigLocation"
  63. value="/WEB-INF/action-servlet.xml.xml,/WEB-INF/applicationContext.xml"/>
  64. </plug-in>
  65. Itispossibletousethisplugintoloadallyourcontextfiles,whichcanbeusefulwhenusingtestingtoolslikeStrutsTestCase.StrutsTestCase'sMockStrutsTestCasewon'tinitializeListenersonstartupsoputtingallyourcontextfilesinthepluginisaworkaround.Abughasbeenfiledforthisissue.
  66. Afterconfiguringthisplug-ininstruts-config.xml,youcanconfigureyourActiontobemanagedbySpring.Spring1.1.3providestwowaystodothis:
  67. OverrideStruts'defaultRequestProcessorwithSpring'sDelegatingRequestProcessor.
  68. UsetheDelegatingActionProxyclassinthetypeattributeofyour<action-mapping>.
  69. BothofthesemethodsallowyoutomanageyourActionsandtheirdependenciesintheaction-context.xmlfile.ThebridgebetweentheActioninstruts-config.xmlandaction-servlet.xmlisbuiltwiththeaction-mapping's"path"andthebean's"name".Ifyouhavethefollowinginyourstruts-config.xmlfile:
  70. <actionpath="/users".../>
  71. YoumustdefinethatAction'sbeanwiththe"/users"nameinaction-servlet.xml:
  72. <beanname="/users".../>
  73. 14.3.1.1.DelegatingRequestProcessor
  74. ToconfiguretheDelegatingRequestProcessorinyourstruts-config.xmlfile,overridethe"processorClass"propertyinthe<controller>element.Theselinesfollowthe<action-mapping>element.
  75. <controller>
  76. <set-propertyproperty="processorClass"
  77. value="org.springframework.web.struts.DelegatingRequestProcessor"/>
  78. </controller>
  79. Afteraddingthissetting,yourActionwillautomaticallybelookedupinSpring'scontextfile,nomatterwhatthetype.Infact,youdon'tevenneedtospecifyatype.Bothofthefollowingsnippetswillwork:
  80. <actionpath="/user"type="com.whatever.struts.UserAction"/>
  81. <actionpath="/user"/>
  82. Ifyou'reusingStruts'modulesfeature,yourbeannamesmustcontainthemoduleprefix.Forexample,anactiondefinedas<actionpath="/user"/>withmoduleprefix"admin"requiresabeannamewith<beanname="/admin/user"/>.
  83. NOTE:Ifyou'reusingTilesinyourStrutsapplication,youmustconfigureyour<controller>withtheDelegatingTilesRequestProcessor.
  84. 14.3.1.2.DelegatingActionProxy
  85. IfyouhaveacustomRequestProcessorandcan'tusetheDelegatingTilesRequestProcessor,youcanusetheDelegatingActionProxyasthetypeinyouraction-mapping.
  86. <actionpath="/user"type="org.springframework.web.struts.DelegatingActionProxy"
  87. name="userForm"scope="request"validate="false"parameter="method">
  88. <forwardname="list"path="/userList.jsp"/>
  89. <forwardname="edit"path="/userForm.jsp"/>
  90. </action>
  91. Thebeandefinitioninaction-servlet.xmlremainsthesame,whetheryouuseacustomRequestProcessorortheDelegatingActionProxy.
  92. IfyoudefineyourActioninacontextfile,thefullfeaturesetofSpring'sbeancontainerwillbeavailableforit:dependencyinjectionaswellastheoptiontoinstantiateanewActioninstanceforeachrequest.Toactivatethelatter,addsingleton="false"toyourAction'sbeandefinition.
  93. <beanname="/user"singleton="false"autowire="byName"
  94. class="org.example.web.UserAction"/>
  95. 14.3.2.ActionSupportClasses
  96. Aspreviouslymentioned,youcanretrievetheWebApplicationContextfromtheServletContextusingtheWebApplicationContextUtilsclass.AneasierwayistoextendSpring'sActionclassesforStruts.Forexample,insteadofsubclassingStruts'Actionclass,youcansubclassSpring'sActionSupportclass.
  97. TheActionSupportclassprovidesadditionalconveniencemethods,likegetWebApplicationContext().BelowisanexampleofhowyoumightusethisinanAction:
  98. publicclassUserActionextendsDispatchActionSupport{
  99. publicActionForwardexecute(ActionMappingmapping,
  100. ActionFormform,
  101. HttpServletRequestrequest,
  102. HttpServletResponseresponse)
  103. throwsException{
  104. if(log.isDebugEnabled()){
  105. log.debug("entering'delete'method...");
  106. }
  107. WebApplicationContextctx=getWebApplicationContext();
  108. UserManagermgr=(UserManager)ctx.getBean("userManager");
  109. //talktomanagerforbusinesslogic
  110. returnmapping.findForward("success");
  111. }
  112. }
  113. SpringincludessubclassesforallofthestandardStrutsActions-theSpringversionsmerelyhaveSupportappendedtothename:
  114. ActionSupport,
  115. DispatchActionSupport,
  116. LookupDispatchActionSupportand
  117. MappingDispatchActionSupport.
  118. Therecommendedstrategyistousetheapproachthatbestsuitsyourproject.Subclassingmakesyourcodemorereadable,andyouknowexactlyhowyourdependenciesareresolved.However,usingtheContextLoaderPluginallowyoutoeasilyaddnewdependenciesinyourcontextXMLfile.Eitherway,Springprovidessomeniceoptionsforintegratingthetwoframeworks.
  119. 14.4.Tapestry
  120. Tapestryisapowerful,component-orientedwebapplicationframeworkfromApache'sJakartaproject(http://jakarta.apache.org/tapestry).WhileSpringhasitsownpowerfulwebuilayer,thereareanumberofuniqueadvantagestobuildingaJ2EEapplicationusingacombinationofTapestryforthewebui,andtheSpringcontainerforthelowerlayers.Thisdocumentattemptstodetailafewbestpracticesforcombiningthesetwoframeworks.ItisexpectedthatyouarerelativelyfamiliarwithbothTapestryandSpringFrameworkbasics,sotheywillnotbeexplainedhere.GeneralintroductorydocumentationforbothTapestryandSpringFrameworkareavailableontheirrespectivewebsites.
  121. 14.4.1.Architecture
  122. AtypicallayeredJ2EEapplicationbuiltwithTapestryandSpringwillconsistofatopUIlayerbuiltwithTapestry,andanumberoflowerlayers,hostedoutofoneormoreSpringApplicationContexts.
  123. UserInterfaceLayer:
  124. -concernedwiththeuserinterface
  125. -containssomeapplicationlogic
  126. -providedbyTapestry
  127. -asidefromprovidingUIviaTapestry,codeinthislayerdoesitsworkviaobjectswhichimplementinterfacesfromtheServiceLayer.TheactualobjectswhichimplementtheseservicelayerinterfacesareobtainedfromaSpringApplicationContext.
  128. ServiceLayer:
  129. -applicationspecific'service'code
  130. -workswithdomainobjects,andusestheMapperAPItogetthosedomainobjectsintoandoutofsomesortofrepository(database)
  131. -hostedinoneormoreSpringcontexts
  132. -codeinthislayermanipulatesobjectsinthedomainmodel,inanapplicationspecificfashion.Itdoesitsworkviaothercodeinthislayer,andviatheMapperAPI.Anobjectinthislayerisgiventhespecificmapperimplementationsitneedstoworkwith,viatheSpringcontext.
  133. -sincecodeinthislayerishostedintheSpringcontext,itmaybetransactionallywrappedbytheSpringcontext,asopposedtomanagingitsowntransactions
  134. DomainModel:
  135. -domainspecificobjecthierarchy,whichdealswithdataandlogicspecifictothisdomain
  136. -althoughthedomainobjecthierarchyisbuiltwiththeideathatitispersistedsomehowandmakessomegeneralconcessionstothis(forexample,bidirectionalrelationships),itgenerallyhasnoknowledgeofotherlayers.Assuch,itmaybetestedinisolation,andusedwithdifferentmappingimplementationsforproductionvs.testing.
  137. -theseobjectsmaybestandalone,orusedinconjunctionwithaSpringapplicationcontexttotakeadvantageofsomeofthebenefitsofthecontext,e.g.,isolation,inversionofcontrol,differentstrategyimplementations,etc.
  138. DataSourceLayer:
  139. -MapperAPI(alsocalledDataAccessObjects):anAPIusedtopersistthedomainmodeltoarepositoryofsomesort(generallyaDB,butcouldbethefilesystem,memory,etc.)
  140. -MapperAPIimplementations:oneormorespecificimplementationsoftheMapperAPI,forexample,aHibernate-specificmapper,aJDO-specificmapper,JDBC-specificmapper,oramemorymapper.
  141. -mapperimplementationsliveinoneormoreSpringApplicationContexts.Aservicelayerobjectisgiventhemapperobjectsitneedstoworkwithviathecontext.
  142. Database,filesystem,orotherrepositories:
  143. -objectsinthedomainmodelarestoredintooneormorerepositoriesviaoneormoremapperimplementations
  144. -arepositorymaybeverysimple(e.g.filesystem),ormayhaveitsownrepresentationofthedatafromthedomainmodel(i.e.aschemainadb).Itdoesnotknowaboutotherlayershowerver.
  145. 14.4.2.Implementation
  146. Theonlyrealquestion(whichneedstobeaddressedbythisdocument),ishowTapestrypagesgetaccesstoserviceimplementations,whicharesimplybeansdefinedinaninstanceoftheSpringApplicationContext.
  147. 14.4.2.1.Sampleapplicationcontext
  148. AssumewehavethefollowingsimpleApplicationContextdefinition,inxmlform:
  149. <?xmlversion="1.0"encoding="UTF-8"?>
  150. <!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN"
  151. "http://www.springframework.org/dtd/spring-beans.dtd">
  152. <beans>
  153. <!--=========================GENERALDEFINITIONS=========================-->
  154. <!--=========================PERSISTENCEDEFINITIONS=========================-->
  155. <!--theDataSource-->
  156. <beanid="dataSource"class="org.springframework.jndi.JndiObjectFactoryBean">
  157. <propertyname="jndiName"><value>java:DefaultDS</value></property>
  158. <propertyname="resourceRef"><value>false</value></property>
  159. </bean>
  160. <!--defineaHibernateSessionfactoryviaaSpringLocalSessionFactoryBean-->
  161. <beanid="hibSessionFactory"
  162. class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
  163. <propertyname="dataSource"><refbean="dataSource"/></property>
  164. </bean>
  165. <!--
  166. -Definesatransactionmanagerforusageinbusinessordataaccessobjects.
  167. -Nospecialtreatmentbythecontext,justabeaninstanceavailableasreference
  168. -forbusinessobjectsthatwanttohandletransactions,e.g.viaTransactionTemplate.
  169. -->
  170. <beanid="transactionManager"
  171. class="org.springframework.transaction.jta.JtaTransactionManager">
  172. </bean>
  173. <beanid="mapper"
  174. class="com.whatever.dataaccess.mapper.hibernate.MapperImpl">
  175. <propertyname="sessionFactory"><refbean="hibSessionFactory"/></property>
  176. </bean>
  177. <!--=========================BUSINESSDEFINITIONS=========================-->
  178. <!--AuthenticationService,includingtxinterceptor-->
  179. <beanid="authenticationServiceTarget"
  180. class="com.whatever.services.service.user.AuthenticationServiceImpl">
  181. <propertyname="mapper"><refbean="mapper"/></property>
  182. </bean>
  183. <beanid="authenticationService"
  184. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  185. <propertyname="transactionManager"><refbean="transactionManager"/></property>
  186. <propertyname="target"><refbean="authenticationServiceTarget"/></property>
  187. <propertyname="proxyInterfacesOnly"><value>true</value></property>
  188. <propertyname="transactionAttributes">
  189. <props>
  190. <propkey="*">PROPAGATION_REQUIRED</prop>
  191. </props>
  192. </property>
  193. </bean>
  194. <!--UserService,includingtxinterceptor-->
  195. <beanid="userServiceTarget"
  196. class="com.whatever.services.service.user.UserServiceImpl">
  197. <propertyname="mapper"><refbean="mapper"/></property>
  198. </bean>
  199. <beanid="userService"
  200. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  201. <propertyname="transactionManager"><refbean="transactionManager"/></property>
  202. <propertyname="target"><refbean="userServiceTarget"/></property>
  203. <propertyname="proxyInterfacesOnly"><value>true</value></property>
  204. <propertyname="transactionAttributes">
  205. <props>
  206. <propkey="*">PROPAGATION_REQUIRED</prop>
  207. </props>
  208. </property>
  209. </bean>
  210. </beans>
  211. InsidetheTapestryapplication,weneedtoloadthisapplicationcontext,andallowTapestrypagestogettheauthenticationServiceanduserServicebeans,whichimplementtheAuthenticationServiceandUserServiceinterfaces,respectively.
  212. 14.4.2.2.ObtainingbeansinTapestrypages
  213. Atthispoint,theapplicationcontextisavailabletoawebapplicationbycallingSpring'sstaticutilityfunctionWebApplicationContextUtils.getApplicationContext(servletContext),whereservletContextisthestandardServletContextfromtheJ2EEServletspecification.Assuch,onesimplemechanismforapagetogetaninstanceoftheUserService,forexample,wouldbewithcodesuchas:
  214. WebApplicationContextappContext=WebApplicationContextUtils.getApplicationContext(
  215. getRequestCycle().getRequestContext().getServlet().getServletContext());
  216. UserServiceuserService=(UserService)appContext.getBean("userService");
  217. ...somecodewhichusesUserService
  218. Thismechanismdoeswork.Itcanbemadealotlessverbosebyencapsulatingmostofthefunctionalityinamethodinthebaseclassforthepageorcomponent.However,insomerespectsitgoesagainsttheInversionofControlapproachwhichSpringencourages,whichisbeingusedinotherlayersofthisapp,inthatideallyyouwouldlikethepagetonothavetoaskthecontextforaspecificbeanbyname,andinfact,thepagewouldideallynotknowaboutthecontextatall.
  219. Luckily,thereisamechanismtoallowthis.WerelyuponthefactthatTapestryalreadyhasamechanismtodeclarativelyaddpropertiestoapage,anditisinfactthepreferredapproachtomanageallpropertiesonapageinthisdeclarativefashion,sothatTapestrycanproperlymanagetheirlifecycleaspartofthepageandcomponentlifecycle.
  220. 14.4.2.3.ExposingtheapplicationcontexttoTapestry
  221. FirstweneedtomaketheApplicationContextavailabletotheTapestrypageorComponentwithouthavingtohavetheServletContext;thisisbecauseatthestageinthepage's/component'slifecyclewhenweneedtoaccesstheApplicationContext,theServletContextwon'tbeeasilyavailabletothepage,sowecan'tuseWebApplicationContextUtils.getApplicationContext(servletContext)directly.OnewayisbydefiningacustomversionoftheTapestryIEnginewhichexposesthisforus:
  222. packagecom.whatever.web.xportal;
  223. ...
  224. import...
  225. ...
  226. publicclassMyEngineextendsorg.apache.tapestry.engine.BaseEngine{
  227. publicstaticfinalStringAPPLICATION_CONTEXT_KEY="appContext";
  228. /**
  229. *@seeorg.apache.tapestry.engine.AbstractEngine#setupForRequest(org.apache.tapestry.request.RequestContext)
  230. */
  231. protectedvoidsetupForRequest(RequestContextcontext){
  232. super.setupForRequest(context);
  233. //insertApplicationContextinglobal,ifnotthere
  234. Mapglobal=(Map)getGlobal();
  235. ApplicationContextac=(ApplicationContext)global.get(APPLICATION_CONTEXT_KEY);
  236. if(ac==null){
  237. ac=WebApplicationContextUtils.getWebApplicationContext(
  238. context.getServlet().getServletContext()
  239. );
  240. global.put(APPLICATION_CONTEXT_KEY,ac);
  241. }
  242. }
  243. }
  244. ThisengineclassplacestheSpringApplicationContextasanattributecalled"appContext"inthisTapestryapp's'Global'object.MakesuretoregisterthefactthatthisspecialIEngineinstanceshouldbeusedforthisTapestryapplication,withanentryintheTapestryapplicationdefinitionfile.Forexample:
  245. file:xportal.application:
  246. <?xmlversion="1.0"encoding="UTF-8"?>
  247. <!DOCTYPEapplicationPUBLIC
  248. "-//ApacheSoftwareFoundation//TapestrySpecification3.0//EN"
  249. "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  250. <application
  251. name="WhateverxPortal"
  252. engine-class="com.whatever.web.xportal.MyEngine">
  253. </application>
  254. 14.4.2.4.Componentdefinitionfiles
  255. Nowinourpageorcomponentdefinitionfile(*.pageor*.jwc),wesimplyaddproperty-specificationelementstograbthebeansweneedoutoftheApplicationContext,andcreatepageorcomponentpropertiesforthem.Forexample:
  256. <property-specificationname="userService"
  257. type="com.whatever.services.service.user.UserService">
  258. global.appContext.getBean("userService")
  259. </property-specification>
  260. <property-specificationname="authenticationService"
  261. type="com.whatever.services.service.user.AuthenticationService">
  262. global.appContext.getBean("authenticationService")
  263. </property-specification>
  264. TheOGNLexpressioninsidetheproperty-specificationspecifiestheinitialvaluefortheproperty,asabeanobtainedfromthecontext.Theentirepagedefinitionmightlooklikethis:
  265. <?xmlversion="1.0"encoding="UTF-8"?>
  266. <!DOCTYPEpage-specificationPUBLIC
  267. "-//ApacheSoftwareFoundation//TapestrySpecification3.0//EN"
  268. "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
  269. <page-specificationclass="com.whatever.web.xportal.pages.Login">
  270. <property-specificationname="username"type="java.lang.String"/>
  271. <property-specificationname="password"type="java.lang.String"/>
  272. <property-specificationname="error"type="java.lang.String"/>
  273. <property-specificationname="callback"type="org.apache.tapestry.callback.ICallback"persistent="yes"/>
  274. <property-specificationname="userService"
  275. type="com.whatever.services.service.user.UserService">
  276. global.appContext.getBean("userService")
  277. </property-specification>
  278. <property-specificationname="authenticationService"
  279. type="com.whatever.services.service.user.AuthenticationService">
  280. global.appContext.getBean("authenticationService")
  281. </property-specification>
  282. <beanname="delegate"class="com.whatever.web.xportal.PortalValidationDelegate"/>
  283. <beanname="validator"class="org.apache.tapestry.valid.StringValidator"lifecycle="page">
  284. <set-propertyname="required"expression="true"/>
  285. <set-propertyname="clientScriptingEnabled"expression="true"/>
  286. </bean>
  287. <componentid="inputUsername"type="ValidField">
  288. <static-bindingname="displayName"value="Username"/>
  289. <bindingname="value"expression="username"/>
  290. <bindingname="validator"expression="beans.validator"/>
  291. </component>
  292. <componentid="inputPassword"type="ValidField">
  293. <bindingname="value"expression="password"/>
  294. <bindingname="validator"expression="beans.validator"/>
  295. <static-bindingname="displayName"value="Password"/>
  296. <bindingname="hidden"expression="true"/>
  297. </component>
  298. </page-specification>
  299. 14.4.2.5.Addingabstractaccessors
  300. NowintheJavaclassdefinitionforthepageorcomponentitself,allweneedtodoisaddanabstractgettermethodforthepropertieswehavedefined,toaccessthem.WhenthepageorcomponentisactuallyloadedbyTapestry,itperformsruntimecodeinstrumentationontheclassfiletoaddthepropertieswhichhavebeendefined,andhookuptheabstractgettermethodstothenewlycreatedfields.Forexample:
  301. //ourUserServiceimplementation;willcomefrompagedefinition
  302. publicabstractUserServicegetUserService();
  303. //ourAuthenticationServiceimplementation;willcomefrompagedefinition
  304. publicabstractAuthenticationServicegetAuthenticationService();
  305. Forcompleteness,theentireJavaclass,foraloginpageinthisexample,mightlooklikethis:
  306. packagecom.whatever.web.xportal.pages;
  307. /**
  308. *Allowstheusertologin,byprovidingusernameandpassword.
  309. *Aftersuccessfullyloggingin,acookieisplacedontheclientbrowser
  310. *thatprovidesthedefaultusernameforfuturelogins(thecookie
  311. *persistsforaweek).
  312. */
  313. publicabstractclassLoginextendsBasePageimplementsErrorProperty,PageRenderListener{
  314. /**thekeyunderwhichtheauthenticateduserobjectisstoredinthevisitas*/
  315. publicstaticfinalStringUSER_KEY="user";
  316. /**
  317. *Thenameofacookietostoreontheuser'smachinethatwillidentify
  318. *themnexttimetheylogin.
  319. **/
  320. privatestaticfinalStringCOOKIE_NAME=Login.class.getName()+".username";
  321. privatefinalstaticintONE_WEEK=7*24*60*60;
  322. //---attributes
  323. publicabstractStringgetUsername();
  324. publicabstractvoidsetUsername(Stringusername);
  325. publicabstractStringgetPassword();
  326. publicabstractvoidsetPassword(Stringpassword);
  327. publicabstractICallbackgetCallback();
  328. publicabstractvoidsetCallback(ICallbackvalue);
  329. publicabstractUserServicegetUserService();
  330. publicabstractAuthenticationServicegetAuthenticationService();
  331. //---methods
  332. protectedIValidationDelegategetValidationDelegate(){
  333. return(IValidationDelegate)getBeans().getBean("delegate");
  334. }
  335. protectedvoidsetErrorField(StringcomponentId,Stringmessage){
  336. IFormComponentfield=(IFormComponent)getComponent(componentId);
  337. IValidationDelegatedelegate=getValidationDelegate();
  338. delegate.setFormComponent(field);
  339. delegate.record(newValidatorException(message));
  340. }
  341. /**
  342. *Attemptstologin.
  343. *
  344. *<p>Iftheusernameisnotknown,orthepasswordisinvalid,thenanerror
  345. *messageisdisplayed.
  346. *
  347. **/
  348. publicvoidattemptLogin(IRequestCyclecycle){
  349. Stringpassword=getPassword();
  350. //Doalittleextraworktoclearoutthepassword.
  351. setPassword(null);
  352. IValidationDelegatedelegate=getValidationDelegate();
  353. delegate.setFormComponent((IFormComponent)getComponent("inputPassword"));
  354. delegate.recordFieldInputValue(null);
  355. //Anerror,fromavalidationfield,mayalreadyhaveoccurred.
  356. if(delegate.getHasErrors())
  357. return;
  358. try{
  359. Useruser=getAuthenticationService().login(getUsername(),getPassword());
  360. loginUser(user,cycle);
  361. }
  362. catch(FailedLoginExceptionex){
  363. this.setError("Loginfailed:"+ex.getMessage());
  364. return;
  365. }
  366. }
  367. /**
  368. *Setsupthe{@linkUser}astheloggedinuser,creates
  369. *acookiefortheirusername(forsubsequentlogins),
  370. *andredirectstotheappropriatepage,or
  371. *aspecifiedpage).
  372. *
  373. **/
  374. publicvoidloginUser(Useruser,IRequestCyclecycle){
  375. Stringusername=user.getUsername();
  376. //Getthevisitobject;thiswilllikelyforcethe
  377. //creationofthevisitobjectandanHttpSession.
  378. Mapvisit=(Map)getVisit();
  379. visit.put(USER_KEY,user);
  380. //Afterloggingin,gototheMyLibrarypage,unlessotherwise
  381. //specified.
  382. ICallbackcallback=getCallback();
  383. if(callback==null)
  384. cycle.activate("Home");
  385. else
  386. callback.performCallback(cycle);
  387. //I'vefoundthatfailingtosetamaximumageandapathmeansthat
  388. //thebrowser(IE5.0anyway)quietlydropsthecookie.
  389. IEngineengine=getEngine();
  390. Cookiecookie=newCookie(COOKIE_NAME,username);
  391. cookie.setPath(engine.getServletPath());
  392. cookie.setMaxAge(ONE_WEEK);
  393. //Recordtheuser'susernameinacookie
  394. cycle.getRequestContext().addCookie(cookie);
  395. engine.forgetPage(getPageName());
  396. }
  397. publicvoidpageBeginRender(PageEventevent){
  398. if(getUsername()==null)
  399. setUsername(getRequestCycle().getRequestContext().getCookieValue(COOKIE_NAME));
  400. }
  401. }
  402. 14.4.3.Summary
  403. Inthisexample,we'vemanagedtoallowservicebeansdefinedintheSpringApplicationContexttobeprovidedtothepageinadeclarativefashion.Thepageclassdoesnotknowwheretheserviceimplementationsarecomingfrom,andinfactitiseasytoslipinanotherimplementation,forexample,duringtesting.ThisinversionofcontrolisoneoftheprimegoalsandbenefitsoftheSpringFramework,andwehavemanagedtoextenditallthewayuptheJ2EEstackinthisTapestryapplication.
  404. 14.5.WebWork
  405. WebWorkisawebframeworkdesignedwithsimplicityinmind.It'sbuiltontopofXWork,whichisagenericcommandframework.XWorkalsohasanIoCcontainer,butitisn'tasfull-featuredasSpringandwon'tbecoveredinthissection.WebWorkcontrollersarecalledActions,mainlybecausetheymustimplementtheActioninterface.TheActionSupportclassimplementsthisinterface,anditismostcommonparentclassforWebWorkactions.
  406. WebWorkmaintainsitsownSpringintegrationproject,locatedonjava.netinthexwork-optionalproject.Currently,threeoptionsareavailableforintegratingWebWorkwithSpring:
  407. SpringObjectFactory:overrideXWork'sdefaultObjectFactorysoXWorkwilllookforSpringbeansintherootWebApplicationContext.
  408. ActionAutowiringInterceptor:useaninterceptortoautomaticallywireanAction'sdependenciesasthey'recreated.
  409. SpringExternalReferenceResolver:lookupSpringbeansbasedonthenamedefinedinan<external-ref>elementofan<action>element.
  410. AllofthesestrategiesareexplainedinfurtherdetailinWebWork'sDocumentation.
  411. --------------------------------------------------------------------------------
  412. Prev
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics