Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[JSF]volgorde van phaseListeners bepalen bij kaart-app

Pagina: 1
Acties:

  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
context
In het project waar ik momenteel aan werk, kan een gebruiker een geometrie intekenen op een kaart. Deze kaart kan verschoven en gezoomd worden en de 'state' van de client wordt met directe ajax calls (dwz zonder framework) geupdate. Deze ajax calls worden serverside opgevangen in een phase listener, waar updates worden gemaakt en het antwoord wordt teruggestuurd.

Dit treed allemaal al op in het 3rd party (GIS - zoals 'google maps') framework dat we gebruiken en het werkt onder de meeste omstandigheden goed.

aanleiding
In een bepaalde situatie, wil ik echter meer doen. Bij het verschuiven van een kaart wil ik ook zelfgetekende geometrieen verschuiven. Omdat ik mijn code los wil houden van het framework heb ik een eigen phaseListener (en serialisatiecode) geschreven die dat voor zijn rekening neemt.

Deze phaselistener zet de de coordinaten van mijn geometrie bij de 'beforePhase' om van schermcoordinaten (bv 800, 600) naar kaartcoordinaten (bv 4389832.39203, 230393.23490). Bij de afterphase moeten deze kaartcoordinaten weer terug worden gezet op schermcoordinaten, gebaseerd op de nieuwe 'extent', of 'venster' op de kaart.

probleem
Dat betekend dat de beforePhase moet worden uitgevoerd VOOR dat de kaart wordt verschoven of gezoomd en dat de afterPhase moet worden uitgevoerd NA het pannen/zoomen.

Als het definieeren van PhaseListeners iets lijkt op dat van filters, betekend dat, dat ik mijn phaseListener moet definieeren voor die van het framework. De laatste wordt echter geleverd in de vorm van een aantal jarretjes, waarbij een daarvan een faces-config.xml in de META-INF directory bevat, waarin de voor verschuiven verantwoordelijke phaselistener is gedefinieerd (en nog een andere voor zoomen).

Daarmee wordt mijn probleem uiteindelijk dat ik geen idee heb hoe ik mijn 'phase-listener'-declaratie voor die van het framework (faces-config.xml in jar) zet.

De enige oplossing die ik zo kan bedenken is om een deze specifieke listener ook in een jarretje te stoppen en eerder in het classpath zetten oid. Dat is echter zo foutgevoelig met deployen en tegen-intuitief, dat ik hoopte dat iemand hier met een andere / betere oplossing zou komen.

Localhost is where the heart is


  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Mbt de volgorde van de PhaseListeners kun je eens kijken naar de methoden dat javax.faces.lifecycle.Lifecycle, javax.faces.component.UIViewRoot en/of javax.faces.event.FacesEvent aanbiedt.

Al heb ik meer het idee dat je dit meer moet modularizeren. Gebruik één PhaseListener voor al dat logica, maak de logica abstract/interfaced en bied concrete implementaties aan.

[ Voor 5% gewijzigd door BalusC op 14-01-2009 16:04 ]


  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
Dat laatste lijkt mij ook een prima idee, maar ik heb hier niet de gelegenheid om het framework aan te passen. De phaseListener van de derde partij wordt sowieso getriggert.

(De code die nu geschreven wordt is bedoelt als een laag met functionaliteit die wij standaard aan onze applicaties willen toevoegen. Als de derde partij met een update van zijn framework komt, moet onze software daar niet steeds weer ingeplakt worden.)


Ik kreeg van een collega die ik hierheen linkte nog het advies dat dit artikel op dev.java.net het volgende zei over facelisteners:
PhaseListeners in the jars that are registered in all the faces-config.xml files bundled with your application are fired sequentially, with no guarantee to the order.
Dat zuigt :/.

Ik ga eens kijken naar een alternatief waarin ik de verplaats-berekening client-side kan oplossen (met een apart request om de nieuwe schaal e.d. op te vragen). Thanks voor je input!

[ Voor 3% gewijzigd door SilentStorm op 14-01-2009 16:50 ]

Localhost is where the heart is


  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Sja, de PhaseListeners zouden onafhankelijk van elkaar moeten functioneren. Is er afhankelijkheid, dan moet je het in feite in één PhaseListener oplossen.

Over welke phases hebben we het hier trouwens? Je hebt het telkens over beforePhase en afterPhase. Maar de JSF lifecycle telt 6 phases. De beforePhase van bijv render response treedt later in dan de afterPhase van bijv restore view.

Mij lijkt dit ook wel oplosbaar met een eenvoudige Filter, mits je de data opslaat in de gebruikelijke scopes (request of session). Deze wordt al uitgevoerd voordat de FacesServlet intreedt.

[ Voor 9% gewijzigd door BalusC op 14-01-2009 17:33 ]


  • SilentStorm
  • Registratie: November 2000
  • Laatst online: 27-04 11:59
Het gaat hier om de 2e phase, 'Apply request values'. De data wordt opgeslagen in de request scope. Hmm. Ik moet daar ook bij de request params kunnen, dus dat klinkt eigenlijk als best een goede optie! Ik ben nog maar een half jaartje met jsf aan het spelen en ik zie soms nog onmogelijkheden waar die eigenlijk niet liggen. Ik zit op dat punt natuurlijk wel dat de DOM tree nog niet is opgebouwd en ik dus meer gegevens mee moet sturen in het request vanaf de client. (Dat probleem had ik in restore view ook en ben er toen niet mee verder gegaan. Dat zou ook nog een alternatief kunnen zijn).

Wat .. typisch trouwens, dus de beforephase van de volgende phase optreed, voor de afterphase van de huidige phase? Of geld dat alleen voor die specifieke phases?

Ik heb hier het core jsf boek nog liggen, van Geary & Horstman. Ik moet bekennen dat ik me nog niet tot op dat detail heb ingelezen.. Daar ga ik voor ik weer vragen heb meer werk van maken :)

Localhost is where the heart is


  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

SilentStorm schreef op woensdag 14 januari 2009 @ 20:53:
Het gaat hier om de 2e phase, 'Apply request values'. De data wordt opgeslagen in de request scope. Hmm. Ik moet daar ook bij de request params kunnen, dus dat klinkt eigenlijk als best een goede optie! Ik ben nog maar een half jaartje met jsf aan het spelen en ik zie soms nog onmogelijkheden waar die eigenlijk niet liggen. Ik zit op dat punt natuurlijk wel dat de DOM tree nog niet is opgebouwd en ik dus meer gegevens mee moet sturen in het request vanaf de client. (Dat probleem had ik in restore view ook en ben er toen niet mee verder gegaan. Dat zou ook nog een alternatief kunnen zijn).
Er is in JSF geen "DOM tree" maar een "component tree" ;) Voor de rest klopt het inderdaad dat je de parameterMap gewoon via HttpServletRequest in een Filter kunt benaderen.
Wat .. typisch trouwens, dus de beforephase van de volgende phase optreed, voor de afterphase van de huidige phase? Of geld dat alleen voor die specifieke phases?
JSF lifecycle telt 6 phases. De beforePhase en de afterPhase worden voor desbetreffende phase uitgevoerd afhankelijk van de waarde dat getPhaseId() returnt. Indien deze bijv ANY is, dan zal het bij elke phase uitgevoerd worden. Eerst beforePhase, dan de daadwerkelijke phase en dan afterPhase. Indien deze bijv RENDER_RESPONSE is, dan zal het alleen voor deze phase uitgevoerd worden.
Ik heb hier het core jsf boek nog liggen, van Geary & Horstman. Ik moet bekennen dat ik me nog niet tot op dat detail heb ingelezen.. Daar ga ik voor ik weer vragen heb meer werk van maken :)
Is een aardig boek. Succes :)
Pagina: 1