Introduzione ad Apache Velocity

1. Panoramica

Velocity è un motore di modelli basato su Java.

È un framework Web open source progettato per essere utilizzato come componente di visualizzazione nell'architettura MVC e fornisce un'alternativa ad alcune tecnologie esistenti come JSP.

Velocity può essere utilizzato per generare file XML, SQL, PostScript e molti altri formati basati su testo.

In questo articolo, esploreremo come può essere utilizzato per creare pagine web dinamiche.

2. Come funziona la velocità

La classe principale di Velocity è VelocityEngine .

Orchestra l'intero processo di lettura, analisi e generazione di contenuti utilizzando il modello di dati e il modello di velocità.

In poche parole, ecco i passaggi che dobbiamo seguire per qualsiasi tipica applicazione di velocità:

  • Inizializza il motore di velocità
  • Leggi il modello
  • Metti il ​​modello di dati nell'oggetto contesto
  • Unisci il modello ai dati di contesto ed esegui il rendering della vista

Facciamo un esempio seguendo questi semplici passaggi:

VelocityEngine velocityEngine = new VelocityEngine(); velocityEngine.init(); Template t = velocityEngine.getTemplate("index.vm"); VelocityContext context = new VelocityContext(); context.put("name", "World"); StringWriter writer = new StringWriter(); t.merge( context, writer );

3. Dipendenze di Maven

Per lavorare con Velocity, dobbiamo aggiungere le seguenti dipendenze al nostro progetto Maven:

 org.apache.velocity velocity 1.7   org.apache.velocity velocity-tools 2.0 

L'ultima versione di entrambe queste dipendenze può essere qui: velocity e velocity-tools.

4. Velocity Template Language

Velocity Template Language (VTL) fornisce il modo più semplice e pulito per incorporare il contenuto dinamico in una pagina web utilizzando riferimenti VTL.

Il riferimento VTL nel modello di velocità inizia con $ e viene utilizzato per ottenere il valore associato a quel riferimento. VTL fornisce anche una serie di direttive che possono essere utilizzate per manipolare l'output del codice Java. Queste direttive iniziano con #.

4.1. Riferimenti

Esistono tre tipi di riferimenti in Velocità, variabili, proprietà e metodi:

  • variabili - definite all'interno della pagina utilizzando la direttiva #set o il valore restituito dal campo dell'oggetto Java:
    #set ($message="Hello World")
  • proprietà - fare riferimento a campi all'interno di un oggetto; possono anche fare riferimento a un metodo getter della proprietà:
    $customer.name
  • metodi : fare riferimento al metodo sull'oggetto Java:
    $customer.getName()

Il valore finale risultante da ogni riferimento viene convertito in una stringa quando viene visualizzato nell'output finale.

4.2. Direttive

VTL fornisce una ricca serie di direttive:

  • set - può essere utilizzato per impostare il valore di un riferimento; questo valore può essere assegnato a una variabile oa un riferimento di proprietà:
    #set ($message = "Hello World") #set ($customer.name = "Brian Mcdonald")
  • condizionali : le direttive #if, #elseif e #else forniscono un modo per generare il contenuto in base ai controlli condizionali:
    #if($employee.designation == "Manager") 

    Manager

    #elseif($employee.designation == "Senior Developer")

    Senior Software Engineer

    #else

    Trainee

    #end
  • loops - La direttiva #foreach consente il loop su una raccolta di oggetti:
    
          
      #foreach($product in $productList)
    • $product
    • #end
  • include - L' elemento #include offre la possibilità di importare file nel modello:
    #include("one.gif","two.txt","three.html"...)
  • parse - L' istruzione #parse consente al progettista del modello di importare un altro file locale che contiene VTL; Velocity analizzerà quindi il contenuto e lo visualizzerà:
    #parse (Template)
  • evaluate#evaluate directive can be used to evaluate VTL dynamically; this allows the template to evaluate a String at render time, for example to internationalise the template:
    #set($firstName = "David") #set($lastName = "Johnson") #set($dynamicsource = "$firstName$lastName") #evaluate($dynamicsource)
  • break#break directive stops any further rendering of current execution scope (i.e. #foreach, #parse)
  • stop#stop directive stops any further rendering and execution of the template.
  • velocimacros#macro directive allows the template designer to define a repeated segment of VTL:
    #macro(tablerows)  #end

    This macro now can be put in any place in the template as #tablerows():

    #macro(tablerows $color $productList) #foreach($product in $productList) $product.name #end #end

4.3. Other Features

  • math – a handful built-in mathematical functions, which can be used in templates:
    #set($percent = $number / 100) #set($remainder = $dividend % $divisor)
  • range operator – that can be used in conjunction with #set and #foreach:
    #set($array = [0..10]) #foreach($elem in $arr) $elem #end

5. Velocity Servlet

The primary job of the Velocity Engine is to generate content based on a template.

The Engine doesn't contain any web related functionalities in itself. To implement a web application, we need to use a servlet or servlet-based framework.

Velocity provides one out of the box implementation VelocityViewServlet, which is a part of the velocity-tools subproject.

To make use of the built-in functionality provided by VelocityViewServlet, we can extend our servlet from VelocityViewServlet and override the handleRequest() method:

public class ProductServlet extends VelocityViewServlet { ProductService service = new ProductService(); @Override public Template handleRequest( HttpServletRequest request, HttpServletResponse response, Context context) throws Exception { List products = service.getProducts(); context.put("products", products); return getTemplate("index.vm"); } }

6. Configuration

6.1. Web Configuration

Let's now see how to configure the VelocityViewServlet in the web.xml.

We need to specify the optional initialization parameters which include velocity.properties and toolbox.xml:

 apache-velocity //...  velocity org.apache.velocity.tools.view.VelocityViewServlet  org.apache.velocity.properties /WEB-INF/velocity.properties   //...  

We also need to specify the mapping for this servlet. All the requests for velocity templates (*.vm) need to be served by the velocity servlet:

 velocityLayout *.vm 

6.2. Resource Loader

Velocity provides flexible resource loader system. It allows one or more resource loader to be in operation at the same time:

  • FileResourceLoader
  • JarResourceLoader
  • ClassPathResourceLoader
  • URLResourceLoader
  • DataSourceResourceLoader
  • WebappResourceLoader

These resource loaders are configured in velocity.properties:

resource.loader=webapp webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader webapp.resource.loader.path = webapp.resource.loader.cache = true

7. Velocity Template

Velocity template is the place where all the view generation logic is written. These pages are written using Velocity Template Language (VTL):

 ...   ... 

$products.size() Products on Sale!

We are proud to offer these fine products at these amazing prices. ... #set( $count = 1 )

#foreach( $product in $products ) #set( $count = $count + 1 ) #end
Serial # Product Name Price
$count) $product.getName() $product.getPrice()

8. Managing the Page Layout

Velocity provides a simple layout control and customizable error screens for Velocity Tool based application.

VelocityLayoutServlet encapsulates this capability to render the specified layouts. VelocityLayoutServlet is an extension to VelocityViewServlet.

8.1. Web Configuration

Let's see how to configure the VelocityLayoutServlet. The servlet is defined for intercepting the requests for velocity template pages and the layout specific properties are defined in velocity.properties file:

 // ...  velocityLayout org.apache.velocity.tools.view.VelocityLayoutServlet  org.apache.velocity.properties /WEB-INF/velocity.properties   // ...  velocityLayout *.vm  // ... 

8.2. Layout Templates

Layout template defines the typical structure of a velocity page. By default, the VelocityLayoutServlet searches for Default.vm under the layout folder. Overriding few properties can change this location:

tools.view.servlet.layout.directory = layout/ tools.view.servlet.layout.default.template = Default.vm 

The layout file consists of header template, footer template, and a velocity variable $screen_content which renders the contents of requested velocity page:

  Velocity #parse("/fragments/header.vm") $screen_content #parse("/fragments/footer.vm") 

8.3. Layout Specification in the Requested Screen

Layout for a particular screen can be defined as a velocity variable at the beginning of a page. That is done by putting this line in the page:

#set($layout = "MyOtherLayout.vm")

8.4. Layout Specification in the Request Parameter

We can add a request parameter in the query string layout=MyOtherLayout.vm and VLS will find it and render the screen within that layout instead of searching for default layout.

8.5. Error Screens

Customized error screen can be implemented using velocity layout. VelocityLayoutServlet provides two variables $error_cause and $stack_trace to present the exception details.

Error page can be configured in velocity.properties file:

tools.view.servlet.error.template = Error.vm

9. Conclusion

In questo articolo abbiamo visto come Velocity sia uno strumento utile per il rendering delle pagine web dinamiche. Inoltre, abbiamo visto diversi modi di utilizzare i servlet forniti dalla velocità.

Abbiamo anche un articolo incentrato su una configurazione Velocity con Spring MVC qui a Baeldung.

Il codice completo per questo tutorial è disponibile su GitHub.