Tải bản đầy đủ - 0 (trang)
Chapter 9. Extending the Struts Framework

Chapter 9. Extending the Struts Framework

Tải bản đầy đủ - 0trang

9.1WhatAreExtensionPoints?

Thinkofaframeworkasahousethatcomeswithpartofthe

structurealreadycomplete,butgivesyoutheoptiontomodify

certaincharacteristics,suchasthewallpaperandpaintcolors.

Ifthedefaultcharacteristicsalreadysuityourneeds,youdon't

havetochangeanything.Ifyoulikethepaintjob,forexample,

that'sonelessthingtoworryabout.

Thisissimilartohowaframeworkfunctions,andthat'sabig

advantagewhenbuildingapplications.Iffunctionalitythatsuits

theneedsofyourapplicationispresentintheframework,you

don'thavetoworryaboutthataspectoftheapplication.This,in

turn,freesupdeveloperstofocusonthecoreapplicationrather

thantheinfrastructure.

Thisisnotaperfectanalogy,butthepointisthatagood

frameworkshouldprovidemuchoftheinfrastructurethe

foundationandtheplumbing,forexample.Themostimportant

aspectofaframework,however,isthatitshouldprovide

extensionpointsthroughout.

Frameworkextensionpoints,alsoreferredtoas"hooks,"allow

youtoextendtheframeworkinspecificplacestoadaptitto

meettheapplication'srequirements.Whereandhowa

frameworkprovidesthesehooksisveryimportant.Ifthey're

providedincorrectlyorinthewronglocations,itbecomesvery

hardforanapplicationtoadapttheframework,whichmakes

theframeworklessuseful.Ifyouextendtheframeworkin

placeswheretherearenoextensionspointsorinwaysthatthe

frameworkauthorsneverintended,upgradingtheapplicationto

newerversionsoftheframeworkbecomesproblematic.Therest

ofthischapterfocusesonwheretheStrutsframeworkprovides

theseextensionpointsandhowyoucantakeadvantageof

themtobuildoutspecializedfunctionalityforyourapplication.



9.2GeneralExtensionPoints

Thissectiondiscussessomeextensionpointsthataffectthe

overallframework,notnecessarilyoneparticularlayer.Arguably

themostimportantoftheseisthePlugInmechanism.



9.2.1UsingthePlugInMechanism

TheStrutsframeworkprovidesamechanismtoallow

componentstobepluggedinandloadeddynamically.This

featurewasaddedinVersion1.1andissupportedthroughthe

useoftheorg.apache.struts.action.PlugIninterface.Any

Javaclasscanfunctionasaplug-in,aslongasitimplements

thePlugIninterface.

Aplug-inissimplyanyJavaclassthatyouneedtoinitialize

whentheStrutsapplicationstartsup,anddestroywhenthe

applicationshutsdown.

ThePlugIninterfacecontainstwomethods,asshownin

Example9-1.



Example9-1.Theorg.apache.struts.action.PlugIn

interface

publicinterfacePlugIn{

/**

*Notificationthatthespecifiedmoduleisbeingstarted.

*/



publicvoidinit(ActionServletservlet,ModuleConfigconfig)

throwsServletException;



/**

*Notificationthatthemoduleisbeingshutdown.

*/

publicvoiddestroy();

}



DuringstartupofaStrutsapplication,theActionServletcalls

theinit()methodforeachPlugInthatisconfigured;the

frameworksupportsconfigurationofoneormorePlugInsfor

eachapplication.Initializationroutinesthatyourplug-inneeds

toperformshouldbedoneduringtheinit()method.Thisisa

goodtimetoinitializeadatabaseconnectionorestablisha

connectiontoaremotesystem,forexample.[1]

[1]Youalsocaninitializeadatabaseconnectionthroughtheuseofadatasource.



Thesecondmethodthatyourplug-inmustimplementisthe

destroy()method.Theframeworkcallsthismethodwhenthe

applicationisbeingshutdown.Youshouldperformany

necessarycleanupduringthistime.Forexample,thisisthe

perfecttimetoclosedatabaseconnections,remotesockets,or

anyotherresourcesthattheplug-inisusing.

Let'sprovideaconcreteexampleofhowtousetheStruts

framework'sPlugInmechanism.Supposethatyourapplication



needstheabilitytocommunicatewithanEJBtier.Oneofthe

firstthingsyoumustdobeforethatcanoccuristogeta

referencetotheJavaNamingandDirectoryInterface(JNDI)

service.JNDIenablesclientstoaccessvariousnamingand

directoryservices,suchasdatasources,JavaMailsessions,and

EJBhomefactories.Example9-2illustratesasimpleexampleof

acquiringanInitialContextforaJNDIserviceusingthe

StrutsPlugInmechanism.



Example9-2.AnexampleofusingtheStruts

PlugInmechanism

packagecom.oreilly.struts.storefront.framework.ejb;



importjava.util.Hashtable;

importjavax.naming.InitialContext;

importjavax.naming.Context;

importorg.apache.struts.action.ActionServlet;

importorg.apache.struts.config.ModuleConfig;

importorg.apache.struts.action.PlugIn;

importjavax.servlet.ServletException;



publicclassJNDIConnectorPluginimplementsPlugIn{

privateStringjndiFactoryClass;



privateStringjndiURL;

privateContextinitCtx=null;



publicJNDIConnectorPlugin(){

super();

}



publicvoidinit(ActionServletservlet,ModuleConfigconfig)

throwsServletException{



//GetthehostandportwheretheJNDIserviceisrunnin



jndiFactoryClass=servlet.getInitParameter("jndi-factory

jndiURL=servlet.getInitParameter("jndi-url");



try{

Hashtableprops=newHashtable();



//TheEJBspecalsoallowsthesetobereadfromthej



props.put(Context.INITIAL_CONTEXT_FACTORY,jndiFactory

props.put(Context.PROVIDER_URL,jndiURL);

initCtx=newInitialContext(props);



}catch(Exceptionex){

thrownewServletException(ex);

}

//StoretheJNDIContextintotheServletContext



servlet.getServletContext().setAttribute("Storefront.In

}



publicvoiddestroy(){

try{

if(initCtx!=null){

initCtx.close();

initCtx=null;



//NoneedtoremovefromServletContextbecauseappis

}

}catch(Exceptionex){

ex.printStackTrace();

}

}



}



Whentheframeworkcallstheinit()methodofthe

JNDIConnectorPluginclass,theplug-increatesan

InitialContextobjectandstoresitintotheServletContext.

ThisallowstheJNDIInitialContexttobeusedbytheentire

application,whenneeded.

Thisisjustasimpleexample;therearemanypossibleusesfor

thePlugInmechanism.Forexample,theValidatorframework,

whichwe'lldiscussinChapter11,usesthePlugInmechanism

toinitializethevalidationrulesforanapplication.



9.2.1.1Addingtheplug-intotheconfiguration

file

Theplug-inmustbedeclaredintheStrutsconfigurationfilein

orderfortheframeworktobeawareofitandinitializeitat

startup.It'sspecifiedintheconfigurationfileusingtheplug-in

element:




className="com.oreilly.struts.storefront.framework.ejb.JNDIC



YoualsocanpasspropertiestoyourPlugInclassbyusingthe

set-propertyelement.



Ifmorethanoneplug-inelementisspecified,theywillbeinitializedin

theorderinwhichtheyarelistedintheconfigurationfile.



Formoreinformationonconfiguringtheplug-inelementor

passingpropertiestoaninstance,seeSection4.6.



9.2.2ExtendingtheStrutsConfigurationClasses

OneofthebiggestchangestoVersion1.1oftheStruts

frameworkistheorg.apache.struts.configpackage.This

packagecontainsalloftheclassesthatareusedasin-memory

representationsoftheinformationstoredintheStruts

configurationfile.TheyrepresenteverythingfromAction

configurationstoPlugInconfigurations.

IfyoulookbackatChapter4,you'llseethatmostofthe

configurationelementsintheStrutsconfigurationfileallowyou

tosupplyafullyqualifiedJavaclassnamefortheconfiguration

classthroughtheclassNameattribute.Thisgivesyouthe

freedomtocustomizetheconfigurationelementandpass

additionalinformation.

Forexample,supposethatyouwanttopassanadditional

parametertoyourActionclasses.Bydefault,the

ActionMappingclass,whichextendsActionConfigfromthe

configpackage,isused.Topassanadditionalparametercalled

ssl-requiredthatcontrolswhetherHTTPorHTTPSisused,

youcanextendtheActionMappingclassandconfigurethis

extensionthroughtheclassNameattribute.Theabilityto

extendtheStrutsconfigurationelementsthroughthis

mechanismmakestheframeworkextremelyextensibleand

flexibleenoughtomeetjustaboutanyapplicationneed.



9.3ControllerExtensionPoints

Thenextsetofpossibleextensionpointsiswithinthecontroller

layer.Someofthesehavebeenmentionedbrieflyinprevious

chapters,butthey'rerepeatedhereforcompleteness.



9.3.1ExtendingtheActionServletClass

InearlierversionsoftheStrutsframework,itwasalmosta

giventhatanapplicationneededtoextendtheActionServlet

classbecausemostofthecontrollerfunctionality,excludingthe

Actionclassbehavior,waspresentinthisclass.WithStruts

1.1,thisisnolongertrue.However,therearestillafewgood

reasonswhyyoumightneedtoextendtheActionServlet

class.

AswaspointedoutinChapter5,theinitializationroutinesthat

areinvokedwhenaStrutsapplicationisfirstlaunchedresidein

theActionServletclass.Ifyouneedtomodifythewaythe

frameworkinitializesitself,thisisoneoftheplacestodoso.To

extendtheActionServletclass,justcreateasubclassof

org.apache.struts.action.ActionServlet.Youcanthen

overridethemethodormethodsthatyouneedtofunction

differently.Oncethisisdone,youneedtomodifythe

deploymentdescriptorsothattheStrutsapplicationwilluse

yourcustomActionServlet:



storefront





com.oreilly.struts.storefront.framework.ExtendedActionServle









Mostoftheruntimerequest-processingbehaviorhasbeen

movedtotheRequestProcessorclassinStruts1.1.Ifyou

needtocustomizethemannerinwhichyourStrutsapplication

processesarequest,seethenextsection.



9.3.2ExtendingtheRequestProcessorClass

Ifyouneedtooverridefunctionalitywithinthe

RequestProcessorclass,youmustlettheframeworkknowthat

itshoulduseyourcustomizedversionratherthanthedefault.

Youcanmaketheframeworkawareofyourspecialized

RequestProcessorbymodifyingtheconfigurationfileforthe

Strutsapplication.Ifyourconfigurationfiledoesn'talreadyhave

acontrollerelementwithinit,you'llneedtoaddone(there

areseveralattributesthatcanbeconfiguredwithinthe

controllerelementseeChapter4formoredetails):


contentType="text/html;charset=UTF-8"

debug="3"

locale="true"

nocache="true"



processorClass="com.oreilly.struts.framework.CustomRequestPro



TheprocessorClassattributeallowsyoutospecifythefully

qualifiedJavaclassnameofyourspecialized

RequestProcessor.TheStrutsframeworkwillcreatean

instanceofyourspecializedRequestProcessoratstartupand

useittoprocessalloftherequestsfortheapplication.Because

eachapplicationmodulecanhaveitsownStrutsconfiguration

file,youcanspecifyadifferentRequestProcessorforeach

module.



9.3.2.1UsingtheprocessPreprocess()method

Therearemanymethodsthatcanbeoverriddenwithinthe

RequestProcessorclass.Oneofthemethodsthatwas

designedwithextensioninmindistheprocessPreprocess()

method.Thismethodiscalledforeachrequest.Bydefault,it

doesnothingwiththerequests,butyoucanusethismethodin

variouswaystochangethedefaultrequest-processingbehavior.

TheprocessPreprocess()methodlookslikethis:



protectedbooleanprocessPreprocess(HttpServletRequestrequest



HttpServletResponserespon

return(true);

}



Thismethodiscalledearlyintherequest-processingstage,

beforetheActionFormiscalledandbeforetheexecute()

methodiscalledontheActionobject.Bydefault,the

processPreprocess()methodreturnstrue,whichtellsthe



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 9. Extending the Struts Framework

Tải bản đầy đủ ngay(0 tr)

×