Стартирайте Velocity Template Engine

Velocity Template Engine ви позволява да изобразявате данни от приложения и сървлети. Използвано главно за разработване на динамични, базирани на сървлети уебсайтове, чистото разделяне на шаблона и Java кода на Velocity го прави идеален за уеб разработка на MVC. Като общ механизъм за шаблони, Velocity отговаря на много други цели, като генериране на код, генериране и преобразуване на XML и обработка на текстови потоци. Тази статия представя езика на шаблоните за скорост (VTL) и предоставя примери за това как да използвате механизма за скорост, включително как да генерирате уеб съдържание в среда на сървлет на Java.

Velocity е инструмент за шаблони с отворен код, разработен от международна доброволческа общност и домакин от проекта на Джакарта на Apache Software Foundation. На уебсайта на проекта за скорост в Джакарта, където можете да изтеглите свободно достъпния изходен код, процъфтяваща и нарастваща общност от потребители е готова да отговори на въпроси и да предложи решения на често срещани проблеми с шаблонирането. Velocity е вдъхновен от пионерския проект WebMacro, работа, за която ние от общността Velocity сме благодарни.

В тази статия представям кратък буквар за Velocity Template Engine и неговия език на шаблона, Velocity Template Language (VTL). Също така демонстрирам как да използвам Velocity чрез няколко примера.

Здравей Свят, разбира се

Никое обяснение на тема, свързана с програмирането, не би било пълно без пример Hello Hello. Всяко приложение, използващо Velocity, изисква две части. Първият е шаблонът, който в този пример е файл, наречен helloworld.vm:

Здравейте $ name! Добре дошли в Velocity!

Втората е съответната Java програма, наречена HelloWorld.java:

импортиране на java.io.StringWriter; импортиране на org.apache.velocity.app.VelocityEngine; внос org.apache.velocity.Template; импортиране на org.apache.velocity.VelocityContext; публичен клас HelloWorld {public static void main (String [] args) хвърля първо изключение {/ *, вземете и инициализирайте двигател * / VelocityEngine ve = new VelocityEngine (); ve.init (); / * следващо, вземете Template * / Template t = ve.getTemplate ("helloworld.vm"); / * създайте контекст и добавете данни * / VelocityContext context = new VelocityContext (); context.put ("име", "Свят"); / * сега визуализира шаблона в StringWriter * / StringWriter писател = нов StringWriter (); t.merge (контекст, автор); / * показване на света * / System.out.println (writer.toString ()); }}

Сега, когато компилирате и стартирате тази програма, ще видите резултата:

Здравей свят! Добре дошли в Velocity!

Това е тривиален пример, но съдържа решаващите парчета, за да ви даде представа за какво става дума при шаблонирането на скоростта.

Защо да го използвам?

Проектиран като лесен за използване общ инструмент за шаблониране, Velocity е полезен във всяка област на приложение на Java, която изисква форматиране на данни и представяне. Трябва да използвате Velocity по следните причини:

  • Той се адаптира към много области на приложение
  • Той предлага прост, ясен синтаксис за дизайнера на шаблони
  • Той предлага прост модел на програмиране за разработчика
  • Тъй като шаблоните и кода са отделни, можете да ги разработвате и поддържате независимо
  • Двигателят Velocity лесно се интегрира във всяка среда на приложение на Java, особено в сървлети
  • Velocity позволява на шаблоните да имат достъп до всеки публичен метод на обекти от данни в контекста

Последната точка е важна - това означава, че можете да използвате повторно съществуващите си класове. Така че обектите, които искате да използвате във вашите шаблони, не трябва да бъдат структурирани по определен начин, като JavaBeans, или да прилагат специални режими на I / O или жизнен цикъл, като таглиби JSP (JavaServer Pages). Единственото изискване е методите да са публични. Ще видите повече от това, когато разгледаме подробно езика на шаблона.

Една от силните страни на Velocity е, че тя силно налага разделяне на функционалната отговорност в приложението. Това се прави чрез ограничаване на достъпа до шаблон до обекти, които кодът на приложението специално предоставя. Това означава, че дизайнерите могат да се фокусират изключително върху представянето на данните (изгледа), а програмистът на приложения може да се съсредоточи върху контрола на приложенията (контролера) и бизнес логиката и управлението на данните (модела) в Model-View-Controller (MVC) развитие. MVC е добре приет модел за разработка, който опростява както разработката, така и текущата поддръжка на сложни приложения.

Къде да го използвам?

Скоростта се използва успешно в:

  • Уеб приложения, базирани на сървлети
  • Генериране на Java и SQL код
  • XML обработка и трансформация
  • Обработка на текст, като генериране на RTF файл

Скоростта е най-често използвана като механизъм за рендиране за разработване на уеб приложения, базирани на сървлети Java, вместо или заедно с JSP и други технологии за рендиране. Освен лесния, поддържаем синтаксис на шаблона, Velocity се използва при уеб разработката, тъй като езикът на неговия шаблон може да манипулира и представя данните, а не да създава данни. Това обезкуражава програмирането в шаблоните. Това е хубаво нещо; той поддържа бизнес и логиката на приложенията на вашия Java там, където им е мястото.

Velocity е много подходящ за уеб разработка на J2EE (Java 2 Platform, Enterprise Edition), тъй като платформата побира изходни технологии, различни от JSP. Докато JSP е включен в спецификацията на J2EE, J2EE не изисква използването му.

Как работи?

Използвате същия общ процес за създаване на приложение, базирано на скорост, както всяко приложение. Нека разгледаме по-интересен пример от приложението Hello World по-горе. Да предположим, че управлявате магазин за домашни любимци и искате да генерирате съобщение по имейл, за да обявите продажба. Първо, трябва да проектирате имейла и след това да разработите шаблона и кода въз основа на този дизайн.

Съображения по време на проектиране

Трябва да вземете предвид три елемента за вашия дизайн:

  • Кои данни да включите в имейла
  • Какво образуват елементите на данните, трябва да приемат (например, както е List, Mapили String)
  • Как да наречем тези елементи от данни

За този пример, нека предположим, че сте избрали три домашни любимци за продажба, всеки с различна обявена цена. Решавате да използвате карта, за да свържете всяко име на домашен любимец и цената му, след което съхранявате и трите карти в списък. Извиквате този списък petList, името на домашния любимец nameи цената, както е priceна картата. След като вече сте идентифицирали съответните данни, тяхното представяне и критерии за именуване, можете да напишете кода и дизайна на шаблона.

Напишете кода и дизайна на шаблона

След като се съгласите относно спецификата на данните, Velocity ви позволява да пишете кода и да проектирате шаблона паралелно. Дизайнерът интегрира данните в съдържанието на презентацията без данни (като изображения, текст и т.н.) в шаблона. В този случай ние просто пишем в тялото на имейла:

$ petList.size () Домашни любимци в продажба! Горди сме да предложим тези фини домашни любимци на тези невероятни цени. Само този месец, изберете от: #foreach ($ pet в $ petList) $ pet.name само за $ pet.price #end Call Today!

Като програмист трябва:

  • Извличане на всички данни от източниците на данни - база данни чрез JDBC (Java Database Connectivity), файл или просто нещо изчислено
  • Поставете тези данни в контекста, като използвате договорените имена
  • Рендерирайте шаблона с контекста, за да получите изход

Може да си спомните от примера Hello World, че аз посочих класа VelocityContextкато контекст . Моделиран след a java.util.Map, контекстът е обект, който съхранява данни, предоставени от приложението или сървлета, до който шаблонът има достъп.

For this example, we get all the data from our data sources (in this case, we hardwire it into the code), organize it, and add it to the context:

 /* create our list of maps */ ArrayList list = new ArrayList(); Map map = new HashMap(); map.put("name", "horse"); map.put("price", "00.00"); list.add( map ); map = new HashMap(); map.put("name", "dog"); map.put("price", "9.99"); list.add( map ); map = new HashMap(); map.put("name", "bear"); map.put("price", ".99"); list.add( map ); /* add that list to a VelocityContext */ VelocityContext context = new VelocityContext(); context.put("petList", list); 

It appears we really want to get rid of those bears!

Now, with the data organized and placed in the context and the template ready, we can render the template against the context. Here is the code:

import java.io.StringWriter; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; public class PetStoreEmail { public static void main( String[] args ) throws Exception { /* first, get and initialize an engine */ VelocityEngine ve = new VelocityEngine(); ve.init(); /* organize our data */ ArrayList list = new ArrayList(); Map map = new HashMap(); map.put("name", "horse"); map.put("price", "00.00"); list.add( map ); map = new HashMap(); map.put("name", "dog"); map.put("price", "9.99"); list.add( map ); map = new HashMap(); map.put("name", "bear"); map.put("price", ".99"); list.add( map ); /* add that list to a VelocityContext */ VelocityContext context = new VelocityContext(); context.put("petList", list); /* get the Template */ Template t = ve.getTemplate( "petstoreemail.vm" ); /* now render the template into a Writer */ StringWriter writer = new StringWriter(); t.merge( context, writer ); /* use the output in your email body */ sendEmail( writer.toString() ); } } 

This complete program generates your email body. Because Velocity renders templates into a Writer, you can easily manage the output. In this case, the rendered output went into a String via the StringWriter, but it could easily have gone to a file, a browser, or a BLOB (binary large object) in a database. This is one reason why Velocity integrates so easily into Java applications.

The program output (your email body) looks like this:

 3 Pets on Sale! We are proud to offer these fine pets at these amazing prices. This month only, choose from: horse for only 00.00 dog for only 9.99 bear for only .99 Call Today! 

Velocity Template Language

I've shown Velocity templates for two different examples, but in neither case have I explained what the special markup did (although you could probably guess).

The Velocity Template Language (VTL) is a simple syntax providing two parts: references, a formalism for accessing objects in the context; and directives, a set of statements used for control and action. Described as "a language definition with a feature set that fits comfortably on a standard business card" (see Jim Jagielski's "Getting Up to Speed with Velocity") VTL has been intentionally kept simple and small by the community.

References

References in the template access data. They freely mix with the template's non-VTL content. Formally defined, a reference is anything in a template that starts with the '$' character and refers to something in the context. If no corresponding data object exists in the context, the template simply treats the reference as text and renders it as-is into the output stream.

Here is a short template containing a simple reference mixed with non-VTL content:

 Hello $name! Welcome to Velocity! 

Here, the reference is $name. As in the Hello World example, Velocity replaces $name in the template with the toString() return value of what is placed in the context under the key name:

 Hello World! Welcome to Velocity! 

The Velocity reference allows access to any object's public method, and the template's syntax is the same as it would be in Java code. Here are a few examples:

 There are $myBean.getSize() elements. $myObject.anotherMethod( 1, "more data ") $foo.getBar().barMethod("hello", $moredata ) $foo.myMethod( $bar.callThis() ) 

You may recall from the Pet Store email example that we stored the name and price information in a java.util.Map, and accessed the data using two tokens name and price, which don't exist as methods in the java.util.Map class:

 $pet.name for only $pet.price 

This works because Velocity incorporates a JavaBean-like introspection mechanism that lets you express method accesses in references using a property notation. In the Pet Store example template, Velocity's introspection facility finds and invokes the Map's public Object get(String) method with the keys name and price. We could access the same data in a different way by invoking the get(String) method directly in the template:

 $pet.get('name') for only $pet.get('price') 

Това би довело до същия резултат и по-добре представя това, което всъщност се случва. Обаче другият начин, който използва нотацията на свойствата, е по-лесен за четене и не обвързва вашия шаблон с конкретното изпълнение на класа данни. Например можете да замените Mapin Listс клас, който има публични методи getName()и getPrice()и оригиналният примерен шаблон, съдържащ следното, ще продължи да работи:

 $ pet.name само за $ pet.price