Programmering

Start Velocity Template Engine

Velocity Template Engine giver dig mulighed for at gengive data fra applikationer og servlets. Primært brugt til at udvikle dynamiske, servlet-baserede websteder, gør Velocitys rene adskillelse af skabelon og Java-kode det ideelt til MVC-webudvikling. Som en generel skabelonmotor passer Velocity til mange andre formål, såsom kodegenerering, XML-generering og transformation og tekstbehandling. Denne artikel introducerer Velocity Template Language (VTL) og giver eksempler på, hvordan man bruger Velocity-motoren, herunder hvordan man genererer webindhold i et Java-servletmiljø.

Velocity er et open source-skabelonværktøj udviklet af et internationalt frivilligt samfund og hostet af Apache Software Foundation Jakarta Project. På webstedet Jakarta Velocity Project, hvor du kan downloade den frit tilgængelige kildekode, er et blomstrende og voksende brugerfællesskab klar til at besvare spørgsmål og tilbyde løsninger på almindelige skabelonproblemer. Velocity blev inspireret af det banebrydende WebMacro-projekt, et arbejde, som vi i Velocity-samfundet er taknemmelige for.

I denne artikel præsenterer jeg en kort primer på Velocity Template Engine og dens skabelonsprog, Velocity Template Language (VTL). Jeg demonstrerer også, hvordan man bruger Velocity gennem flere eksempler.

Hej verden, selvfølgelig

Ingen forklaring på et programmeringsrelateret emne ville være komplet uden et Hello World-eksempel. Enhver applikation, der bruger Velocity, kræver to dele. Den første er skabelonen, som i dette eksempel er en fil, der hedder helloworld.vm:

 Hej $ navn! Velkommen til Velocity! 

Det andet er et tilsvarende Java-program kaldet HelloWorld.java:

importere java.io.StringWriter; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; offentlig klasse HelloWorld {public static void main (String [] args) kaster Undtagelse {/ * først, hent og initialiser en motor * / VelocityEngine ve = new VelocityEngine (); ve.init (); / * næste, hent skabelonen * / skabelon t = ve.getTemplate ("helloworld.vm"); / * opret en kontekst og tilføj data * / VelocityContext context = new VelocityContext (); context.put ("navn", "Verden"); / * gengiv nu skabelonen til en StringWriter * / StringWriter-forfatter = ny StringWriter (); t.merge (kontekst, forfatter); / * vis verden * / System.out.println (writer.toString ()); }} 

Nu, når du kompilerer og kører dette program, vil du se output:

 Hej Verden! Velkommen til Velocity! 

Dette er et trivielt eksempel, men det indeholder de vigtige stykker, der giver dig en idé om, hvad Velocity-skabeloner handler om.

Hvorfor skal jeg bruge det?

Velocity er designet som et brugervenligt generelt skabelonværktøj og er nyttigt i ethvert Java-applikationsområde, der kræver dataformatering og præsentation. Du bør bruge Velocity af følgende grunde:

  • Den tilpasser sig mange anvendelsesområder
  • Det giver en enkel, klar syntaks for skabelondesigneren
  • Det tilbyder en simpel programmeringsmodel til udvikleren
  • Da skabeloner og kode er adskilte, kan du udvikle og vedligeholde dem uafhængigt
  • Velocity-motoren integreres let i ethvert Java-applikationsmiljø, især servlets
  • Velocity giver skabeloner adgang til enhver offentlig metode til dataobjekter i konteksten

Det sidste punkt er vigtigt - det betyder, at du kan genbruge dine eksisterende klasser. Så objekter, du vil bruge i dine skabeloner, behøver ikke at være struktureret på en bestemt måde som f.eks. JavaBeans eller implementere specielle I / O- eller livscyklustilstande, såsom JSP (JavaServer Pages) taglibs. Det eneste krav er, at metoderne er offentlige. Du vil se mere af dette, når vi dækker skabelonsproget i detaljer.

En af Velocitys styrker er, at den kraftigt håndhæver en adskillelse af funktionelt ansvar inden for applikationen. Det gør dette ved at begrænse skabelonadgangen til objekter, som applikationskoden specifikt gør tilgængelig. Dette betyder, at designere udelukkende kan fokusere på datapræsentationen (visningen), og applikationsprogrammereren kan fokusere på applikationskontrollen (controlleren) og forretningslogikken og datastyringen (modellen) i Model-View-Controller (MVC) udvikling. MVC er et godt accepteret udviklingsmønster, der forenkler både udvikling og løbende vedligeholdelse af sofistikerede applikationer.

Hvor bruger jeg det?

Hastighed bruges med succes i:

  • Servlet-baserede webapplikationer
  • Java- og SQL-kodegenerering
  • XML-behandling og transformation
  • Tekstbehandling, såsom generering af RTF-filer

Velocity bruges mest som en gengivelsesmotor til Java-servletbaseret webapplikationsudvikling i stedet for eller i forbindelse med JSP'er og andre gengivelsesteknologier. Udover den lette, vedligeholdelige skabelonsyntaks, bruges Velocity i webudvikling, fordi dens skabelonsprog kan manipulere og præsentere dataene, ikke oprette data. Dette modvirker programmering inden for skabelonerne. Dette er en god ting; det holder din Java-kodes forretnings- og applikationslogik, hvor de hører hjemme.

Velocity er velegnet til J2EE (Java 2 Platform, Enterprise Edition) Webudvikling, fordi platformen rummer andre outputteknologier end JSP. Mens JSP er inkluderet i J2EE-specifikationen, kræver J2EE ikke brugen.

Hvordan virker det?

Du bruger den samme generelle proces til at oprette en Velocity-baseret applikation som med enhver applikation. Lad os overveje et mere interessant eksempel end Hello World-applikationen ovenfor. Antag at du driver en dyrehandel og ønsker at generere en e-mail-eksplosion for at annoncere et salg. Først skal du designe e-mailen og derefter udvikle skabelonen og koden baseret på dette design.

Design-tid overvejelser

Du skal overveje tre elementer til dit design:

  • Hvilke data der skal medtages i e-mailen
  • Hvilken form skal dataelementerne have (f.eks. Som Liste, Kort, eller Snor)
  • Hvad man skal kalde disse dataelementer

Lad os antage, at du i dette eksempel beslutter at vælge tre kæledyr til salg, hver med en anden annonceret pris. Du beslutter at bruge et kort til at knytte hvert kæledyrsnavn og dets pris og derefter gemme alle tre kort på en liste. Du kalder denne liste petList, kæledyrsnavnet navnog prisen som pris på kortet. Nu hvor du har identificeret de relevante data, dets repræsentation og navngivningskriterier, kan du skrive koden og skabelonens design.

Skriv koden og skabelondesignet

Når du er enig i dataspecifikationer, giver Velocity dig mulighed for at skrive koden og designe skabelonen parallelt. Designeren integrerer dataene i nondata-præsentationsindholdet (som billeder, tekst osv.) I skabelonen. I dette tilfælde skriver vi simpelthen i e-mail-kroppen:

 $ petList.size () Kæledyr til salg! Vi er stolte af at tilbyde disse fine kæledyr til disse fantastiske priser. Vælg kun denne måned: #foreach ($ pet i $ petList) $ pet.name for kun $ pet.price #end Ring i dag! 

Som programmør skal du:

  • Hent alle data fra datakilderne - en database via JDBC (Java Database Connectivity), en fil eller bare noget beregnet
  • Sæt disse data i konteksten ved hjælp af de aftalte navne
  • Geng skabelonen med konteksten for at producere output

Du kan huske fra Hello World-eksemplet, at jeg henviste til klassen VelocityContext som sammenhæng. Modelleret efter en java.util.Kort, er konteksten et objekt, der indeholder data fra applikationen eller servlet, som skabelonen har adgang til.

I dette eksempel får vi alle data fra vores datakilder (i dette tilfælde indbinder vi det i koden), organiserer det og føjer det til konteksten:

 / * opret vores liste over kort * / ArrayList liste = ny ArrayList (); Kortkort = nyt HashMap (); map.put ("navn", "hest"); map.put ("pris", "00,00"); list.add (kort); kort = nyt HashMap (); map.put ("navn", "hund"); map.put ("pris", "9,99"); list.add (kort); kort = nyt HashMap (); map.put ("navn", "bjørn"); map.put ("pris", ".99"); list.add (kort); / * tilføj listen til en VelocityContext * / VelocityContext context = ny VelocityContext (); context.put ("petList", liste); 

Det ser ud til, at vi virkelig vil slippe af med disse bjørne!

Nu med dataene organiseret og placeret i konteksten og skabelonen klar, kan vi gengive skabelonen mod konteksten. Her er koden:

importere java.io.StringWriter; importere java.util.List; importere java.util.ArrayList; importere java.util.Map; importere java.util.HashMap; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; offentlig klasse PetStoreEmail {public static void main (String [] args) kaster Undtagelse {/ * først, hent og initialiser en motor * / VelocityEngine ve = new VelocityEngine (); ve.init (); / * organisere vores data * / ArrayList liste = ny ArrayList (); Kortkort = nyt HashMap (); map.put ("navn", "hest"); map.put ("pris", "00,00"); list.add (kort); kort = nyt HashMap (); map.put ("navn", "hund"); map.put ("pris", "9,99"); list.add (kort); kort = nyt HashMap (); map.put ("navn", "bjørn"); map.put ("pris", ".99"); list.add (kort); / * tilføj denne liste til en VelocityContext * / VelocityContext context = ny VelocityContext (); context.put ("petList", liste); / * hent skabelonen * / skabelon t = ve.getTemplate ("petstoreemail.vm"); / * gengiv nu skabelonen til en Writer * / StringWriter-forfatter = ny StringWriter (); t.merge (kontekst, forfatter); / * brug output i din e-mail-krop * / sendEmail (writer.toString ()); }} 

Dette komplette program genererer din e-mail-krop. Fordi Velocity gengiver skabeloner til en Forfatter, kan du nemt styre output. I dette tilfælde gik det gengivne output til en Snor via StringWriter, men det kunne let være gået til en fil, en browser eller en BLOB (binært stort objekt) i en database. Dette er en af ​​grundene til, at Velocity integreres så let i Java-applikationer.

Programoutputtet (din e-mail-krop) ser sådan ud:

 3 kæledyr til salg! Vi er stolte af at tilbyde disse fine kæledyr til disse fantastiske priser. Vælg kun denne måned: hest til kun 00.00 hund til kun 9.99 bjørn til kun .99 Ring i dag! 

Velocity Template Language

Jeg har vist Velocity-skabeloner til to forskellige eksempler, men i ingen af ​​tilfældene har jeg forklaret, hvad den specielle markering gjorde (selvom du sandsynligvis kunne gætte).

Velocity Template Language (VTL) er en simpel syntaks, der giver to dele: referencer, en formalisme for at få adgang til objekter i konteksten; og direktiver, et sæt udsagn, der bruges til kontrol og handling. Beskrevet som "en sprogdefinition med et funktionssæt, der passer komfortabelt på et standard visitkort" (se Jim Jagielskis "Kom op i hastighed med hastighed") VTL er bevidst holdt enkelt og lille af samfundet.

Referencer

Referencer i skabelonadgangsdata. De blandes frit med skabelonens ikke-VTL-indhold. Formelt defineret er en reference alt i en skabelon, der starter med '$' -tegnet og refererer til noget i sammenhængen. Hvis der ikke findes noget tilsvarende dataobjekt i konteksten, behandler skabelonen simpelthen referencen som tekst og gengiver den som den er i outputstrømmen.

Her er en kort skabelon, der indeholder en simpel reference blandet med ikke-VTL-indhold:

 Hej $ navn! Velkommen til Velocity! 

Her er henvisningen $ navn. Som i Hello World-eksemplet erstatter Velocity $ navn i skabelonen med toString () returværdi af, hvad der er placeret i konteksten under nøglen navn:

 Hej Verden! Velkommen til Velocity! 

Hastighedsreferencen giver adgang til ethvert objekts offentlige metode, og skabelonens syntaks er den samme som den ville være i Java-kode. Her er et par eksempler:

 Der er $ myBean.getSize () -elementer. $ myObject.anotherMethod (1, "flere data") $ foo.getBar (). barMethod ("hej", $ moredata) $ foo.myMethod ($ bar.callThis ()) 

Du husker muligvis fra e-maileksemplet med Pet Store, at vi lagrede navn og prisoplysninger i en java.util.Kortog fik adgang til dataene ved hjælp af to tokens navn og pris, som ikke findes som metoder i java.util.Kort klasse:

 $ pet.name for kun $ pet.pris 

Dette fungerer, fordi Velocity inkorporerer en JavaBean-lignende introspektionsmekanisme, der lader dig udtrykke metodeadgang i referencer ved hjælp af en egenskabsnotation. I eksemplet på skabelonen Pet Store finder Velocitys introspektionsfacilitet og påberåber sig Kort's public Object get (String) metode med tasterne navn og pris. Vi kunne få adgang til de samme data på en anden måde ved at påkalde få (streng) metode direkte i skabelonen:

 $ pet.get ('navn') for kun $ pet.get ('pris') 

Dette ville producere den samme produktion og bedre repræsentere, hvad der faktisk sker. Den anden måde, der bruger ejendomsnotationen, er lettere at læse og binder ikke din skabelon til dataklassen specifikke implementering. For eksempel kan du erstatte Kort i Liste med en klasse, der har offentlige metoder getName () og getPrice (), og den originale eksempelskabelon, der indeholder følgende, fortsætter med at arbejde:

 $ pet.name for kun $ pet.pris