Follow Us on Twitter

Stack Attack: Flex, Spring, JPA en Toplink

Case: SongSearch

Januari 2009 - De meeste Java programmeurs weten tegenwoordig goed dat er erg veel frameworks zijn waar men uit kan kiezen om zijn applicatie op te zetten. Daarnaast merkt deze programmeur ook vaak dat hij meerdere frameworks kan combineren. Uiteindelijk schuilt hierin het gevaar dat een applicatie zoveel frameworks bevat dat de volgende persoon die gaat werken aan de applicatie door de bomen het bos niet meer ziet. Gelukkig kunnen we zeggen dat het gebruik van een of meerdere frameworks de kwaliteit van een applicatie drastisch kan verbeteren.

In dit Whitebook wordt aan de hand van een simpele case een applicatie ontwikkeld met een combinatie van een aantal frameworks en technologieën. De focus ligt op snelle ontwikkeling en flexibiliteit. Het Whitebook is geen stap voor stap handleiding. Het beperkt zich tot de essentiële configuraties en toont de sterke en zwakke punten van de stack.

De case

Stel je voor, je hebt zojuist een nummer gehoord op de radio. Je vindt het een geweldig nummer en wilt het graag kopen. Maar hoe heet dat nummer ook al weer? En wie is de artiest? Zou het niet handig zijn om een applicatie te hebben waarin je een stukje songtekst kunt tikken, en dat de applicatie dan vertelt welk nummer dit is? We gaan er even vanuit dat RDS niet bestaat, en dat applicaties als Shazam en TrackID geen gemeengoed zijn.

Dit is de applicatie die we willen gaan realiseren. We houden het simpel. We hebben 3 entiteiten. Een artiest, een lied en een songtekst. Hieronder ziet u een ERD diagram van de applicatie.

ERD SongSearch

De Stack

Voor het opslaan van de data wordt een MySQL database gebruikt. Voor bewerken van de data wordt Java in combinatie met het Spring 2.5 framework gebruikt. Voor het persisteren van de gegevens in Java naar de database wordt JPA met Toplink gebruikt. Om de gegevens uiteindelijk op een fatsoenlijke manier naar de gebruiker te toveren wordt er gebruik gemaakt van Flex in combinatie met BlazeDS.

Project opzet

Voor een goede start is het handig om van Maven gebruik te maken. Met deze tool is het handig om de eerste opzet van het project te realiseren en gedurende het project de applicatie te compileren, verpakken in een .war en deze te deployen naar de Tomcat server waarop de applicatie gaat draaien. Het opzetten van het .pom bestand voor Maven vergt het meeste tijd. Dit komt vooral door het zoeken van alle dependancies voor de technologieën die we gekozen hebben. Sites zoals www.jarfinder.com en mvnrepository.com zijn hierbij handige hulpmiddelen. Een belangrijke plug-in is de “flex-mojos-repository”.

Hier vind u een snippet met dependancies en plugins uit de pom.xml: pom-snippet.zip.

Spring

Om ervoor te zorgen dat gegevens in de database gepersisteerd kunnen worden moet in de “applicationcontext” JPA geconfigureerd worden. Hier moeten een “EntityManagerFactory” en een “DataSource” bean aangemaakt worden. Hieronder een voorbeeld:

DataSource Bean SongSearch

Door bovenstaande configuratie aan te passen kan er geschakeld worden tussen databases mocht dat ooit nodig zijn.

Hierna kunnen we de beans declareren welke we vanuit Flex willen gaan aanroepen. Voordat we deze beans daadwerkelijk kunnen gebruiken in Flex moeten we een “SpringFactory” aanmaken. Deze SpringFactory wordt later gebruikt in de configuratie van BlazeDS.
Download SpringFactory: springfactory.zip.

Hieronder een gedeelte van de “services-config.xml”:

services-config.xml

 Hieronder een gedeelte van de “remoting-config.xml”:

remoting-config.xml

Hieronder een gedeelte van de “applicationcontext”:

applicationcontext

Zoals u ziet maken we een bean aan van de klasse “ArtistDaoImpl” . Deze bevat de methodes die we vanuit Flex willen aanroepen. In de remoting-config specificeren we dat we de bean “artistDao” van de factory met de naam “spring” terug willen krijgen.

Nu rest ons nog om de Javacode te schrijven.

Het Model

De modelklassen “Artist.java”, “Song.java” en “SongText.java” zorgen er door middel van JPA annotaties voor dat er in de database tabellen met dezelfde naam worden aangemaakt. Andersom is het ook mogelijk wanneer u een bestaande database heeft om bijvoorbeeld met behulp van JDeveloper de modelklassen inclusief annotaties te laten genereren. Dit kan een hoop tijd schelen.

 Songs in SongSearch

Flex scherm met overzicht van de verschillende liedjes en hun songtext.

De DAO klassen

Om de modelklassen te vullen en functies met operaties op deze modelklassen aan te bieden worden er DAO klassen aangemaakt. Deze klassen gebruiken we vanuit Flex om gegevens uit de database op te halen. Het is wijs om voor elke model klasse een eigen DAO klasse aan te maken. Wanneer dit gebeurd is, dan is de backend klaar om aangesloten te worden op de frontend. In dit geval is dat Flex. Maar voordat het zo ver is moet er nog getest worden.

Unit testen

Om er zeker van te zijn dat de DAO klassen correct werken en blijven werken is het van belang om hiervoor unit testen te schrijven. Hieronder een stuk code:

unit test dao class

In de code hierboven zijn een aantal dingen van belang. Er wordt gebruik gemaakt van de klasse “AbstractDependencyInjectionSpringContextTests” welke het mogelijk maakt om in combinatie met de methode “getConfigLocations” de verschillende DAO’s welke gedeclareerd zijn in de code automatisch te creëren. Daarvoor moeten er wel “get” en “set” methoden voor de DAO in de code aanwezig zijn.

Kwaliteit

Dan nog een intermezzo over kwaliteit. Deze applicatie bestaat uit verschillende lagen. Door deze scheiding van functionaliteit wordt de applicatie op zich al beter te beheren. Hoe invulling gegeven wordt aan de code in de verschillende lagen is aan de ontwikkelaar. De huidige opzet van de case hangt al naar een MVC architectuur, waarbij de DAO zou moeten worden gezien als controller. Aan te raden valt om een service klasse te creëren welke alleen de functionaliteit bied die daadwerkelijk nodig is. In Flex valt aan te raden om “Cairngorm” te gebruiken.

Flex

In het Flex project is het nu mogelijk om door middel van een “RemoteObject” Java methodes aan te roepen en de resultaten van deze methodes te gebruiken.

Een “RemoteObject” ziet er als volgt uit:

In het bovenstaande stuk code kunt u zien dat we het “RemoteObject” een id geven en aangeven welke bean het object aanroept. In dit geval is dat de “artistDao” zoals deze in de “remoting-config.xml” is geconfigureerd. Daarnaast geeft ik met de <mx:method> tag aan welke actionscript functie het resultaat van de Java methode afhandelt.

De flexibele magie

Het resultaat van een aanroep naar een “RemoteObject” wordt bijna altijd afgehandeld door een functie. Dit is de “ResultHandler” waarbij een parameter van het type “ResultEvent” wordt meegegeven. Als we aannemen dat deze parameter de naam “event” heeft dan kan men het resultaat van “RemoteObject” terugvinden in “event.result”.

Wanneer het resultaat van een “RemoteObject” (Java functie) een primitief is, bijvoorbeeld een int, dan kan men dit resultaat in Flex ophalen door de code “event.result as int;”. 

Maar wat nu as er nu objecten geretourneerd worden door het “RemoteObject”? Hiervoor is er een krachtige oplossing. In Flex creëren we een modelklasse voor elke Java klasse die in het project bestaat. In Java kennen we de klasse Artist. Daarom hebben we in Flex de volgende klasse aangemaakt.

Flex class SongSearch

In deze klasse is het belangrijk dat de namen van de attributen hetzelfde zijn als die in de Java klasse. Daarnaast geven we door middel van de “RemoteClass” annotatie aan dat deze klasse en de Java klasse bij elkaar horen. Nu ziet Flex automatisch van welke type het object is dat terug komt. Als men bijvoorbeeld een collectie van Artist terug krijgt en men zet het resultaat direct in een DataGrid, dan weet Flex meteen welke kolommen er gemaakt moeten worden, en wordt het DataGrid correct gevuld. Het resultaat van een “RemoteObject” kan nu opgehaald worden door “event.result as ArrayCollection;” of wanneer het geen collectie is door middel van “event.result as Artist;”.

SongSearch Artists

Artiesten met hun liedjes, hiervoor is er maar 1 aanroep geweest naar de backend. Het Artist object bevatte ook alle Songs.

Maar de echte kracht ligt in het feit dat Artist een collectie met Songs bevat. Deze worden ook meegeladen omdat het Java object deze liedjes ook bevatte. Hierdoor kun je met het ophalen van een artiest ook meteen alle liedjes laten zien zonder dat je nogmaals met de server moet praten. Hierin schuilt ook meteen een gevaar. Stel je voor dat je een database hebt met duizenden artiesten. Al deze artiesten hebben een flink aantal liedjes, en dan ook nog eens een songtext. Als je dan alle artiesten probeert te laden in de Flex applicatie wordt er effectief de hele database overgeheveld. Dit is voor de performance natuurlijk niet gewenst. Hier moet van te voren dus goed over nagedacht worden. Veel van deze problemen kunnen al opgelost worden door in JPA bij de relaties het “fetch” attribuut op “lazy” te zetten in plaats van “eager” (fetch = FetchType.LAZY).

De koppeling met de Java backend is nu compleet en het is nu mogelijk om de hele frontend verder in Flex te bouwen. Maar daar gaat dit Whitebook niet over.

Conclusie

In dit Whitebook heeft u kunnen lezen hoe het mogelijk is om met een aantal verschillende frameworks en tools het mogelijk is om snel te kunnen ontwikkelen en toch flexibiliteit en kwaliteit te behouden. Door middel van de gekozen stack is het mogelijk om snel te kunnen schakelen naar een andere database zonder de Java of Flex code aan te passen. Daarnaast hebben we zelf niet eerst met SQL een hele database te hoeven creëren, maar hebben we dit gedaan terwijl we de modelklassen optuigden. We hebben DAO klassen aangemaakt om ontsluiting met de database te controleren. Mocht er meer tijd zijn, dan zou het nog wijs zijn om een “Service” klasse te maken welke een interface naar Flex bied en tegelijkertijd functionaliteit abstraheert. Hierdoor hoeft u dan ook niet meer de DOA klassen beschikbaar te maken voor Flex. En uiteindelijk zorgt Flex in combinatie met BlazeDS ervoor dat er door middel van “Bindings” met klassen en objecten er zo min mogelijk aanroepen naar de backend plaats hoeven vinden. Dit is over het algemeen fijn voor de server, fijn voor de gebruiker want deze heeft minder wachttijd en dit is erg fijn voor de ontwikkelaar. Deze hoeft namelijk minder aanroepen te programmeren vanuit Flex naar Java.

Search SongSearch

Het resultaat: We kunnen songteksten zoeken.

Waar het meeste tijd in gaat zitten, dat is het goed optuigen van het Maven Project. Maar wanneer dit goed gedaan is dan kan men in een mum van tijd applicaties bouwen. Of functionaliteit toevoegen. Hierbij denk ik aan CXF voor webservices, of “spring-security” voor beveiliging.

Over de auteur
Marcel Maas is SOA en Java Consultant, en heeft daarnaast diepgaande kennis over Flex. In zijn vakgebied probeert hij het beste uit al zijn kennisgebieden te combineren om zo een juiste combinatie van flexibiliteit, kwaliteit en snelheid te realiseren.

Waardering:
 

Reacties

Dit is een goed artikel

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.