Quickly generate code using the Velocity template engine

Source: Internet
Author: User

Reprint: http://www.ibm.com/developerworks/cn/java/j-lo-velocity1/

Velocity is a Java-based template engine that allows anyone to simply use the template language to refer to objects defined by Java code, thus separating the interface from the Java code so that the interface designer can synchronize with the Java Program developer to develop a we that follows the MVC architecture b site. But in the practical application, Velocity is not only used in the MVC architecture.

Velocity Template Engine Introduction

In today's software development process, software developers are devoting more effort to repetitive and similar work. Especially in today's particularly popular MVC architecture model, the software functions more independently at all levels, and the code is more similar in similarity. So we need to find a way to reduce the duplication of effort by software developers, and let programmers focus more on business logic and other more creative work. Velocity This template engine can solve this problem to some extent.

Velocity is a Java-based template engine framework that provides a template language that can be used on objects and variables defined in Java. Velocity is a project of the Apache Foundation, and the goal is to separate the persistence and business layers in the MVC pattern. In practice, however, Velocity is not only used in the MVC architecture, but can also be used in some of the following scenarios.

1.WEB Applications: Developers can use Velocity to make HTML dynamic content features without using JSP.

2. Source code generation: Velocity can be used to generate Java code, SQL, or PostScript. A lot of open source and commercially developed software is developed using Velocity.

3. Auto Email: Many software user registration, password reminders or reports are generated using Velocity. Instead of stitching strings in Java code, you can use Velocity to generate message content in a text file.

4. Conversion xml:velocity provides an ant task called Anakia that can read the XML file and let it be read by the Velocity template. A more common application is to convert Xdoc documents into styled HTML files.

Back to top of page

Hello Velocity

As with the order of learning all new languages or frameworks, we start with Hello Velocity. First download the latest release package on Velocity's official website, then use Eclipse to build a common Java project. Introduce the jar package below the Velocity-1.7.jar and Lib folders in the unpack package. So we can use Velocity in the project.

After you finish the preparatory work, you can create a new class called Hellovelocity, with the following code:

Listing 1. Hellovelocity.java
public class Hellovelocity {public static void main (string[] args) {velocityengine ve = new Velocityengine (); Ve.setprop Erty (Runtimeconstants.resource_loader, "classpath"); Ve.setproperty ("Classpath.resource.loader.class", ClasspathResourceLoader.class.getName ());  Ve.init ();  Template t = ve.gettemplate ("HELLOVELOCITY.VM"); Velocitycontext CTX = new Velocitycontext ();  Ctx.put ("name", "Velocity"); Ctx.put ("Date", (new Date ()). ToString ());  List temp = new ArrayList (); Temp.add ("1"); Temp.add ("2"); Ctx.put ("list", temp);  StringWriter SW = new StringWriter ();  T.merge (CTX, SW);  System.out.println (Sw.tostring ()); }}

In Hellovelocity's code, the first new Velocityengine class, which sets up some of the configuration used by Velocity, can read the template generated by HELLOVELOCITY.VM after the engine is initialized. A class. The following Velocitycontext class is the content that is read by the configuration Velocity template. This context can be stored in any type of object or variable for the template to read. This operation is like using JSP development, put Key-value in request, let JSP read the same.

The next step is to write the Hellovelocity.vm file, which actually defines the Velocity's output content and format. The contents of HELLOVELOCITY.VM are as follows:

Listing 2. Hellovelocity.vm
#set ($iAmVariable = "good!") Welcome $name to Velocity.comtoday are $date. #foreach ($i in $list) $i #end$iamvariable

The output results are as follows:

Welcome Velocity to Velocity.comtoday is Sun Mar 19:19:04 CST 2014.12good!

As we can see in the output, $name, $date are replaced with variables defined in Hellovelocity.java, and each element of the list is traversed in a foreach statement and printed out. $iamvariable is a variable defined in the page using #set.

Basic template language Syntax usage

In HELLOVELOCITY.VM, you can see a lot of things that start with # and $, which are the Velocity syntax. All the keywords in Velocity start with #, and all the variables start with $. Velocity's syntax is similar to JSTL in JSPs, and even functions-like macros can be defined, following a look at the specific syntax rules.

One, variable

Like other programming languages we know, Velocity can also have variable concepts in template files.

1. Variable definition

#set ($name = "velocity")

The string Velocity engine after the equals sign will be re-parsed, for example, when a string starting with $ is made, the variable will be replaced.

#set ($hello = "Hello $name")

The above equation will give $hello a value of "Hello Velocity".

2. Use of variables

Use $name or ${name} in the template file to work with the defined variables. It is recommended to use the format ${name}, because in the template it is possible to define two variables similar to $name and $names, and if you do not use braces, the engine will not be able to correctly identify the variable $names.

For a variable of a complex object type, such as $person, you can use ${person.name} to access the person's Name property. It is worth noting that the ${person.name} here does not directly access the person's Name property, but instead accesses the person's GetName () method, so ${person.name} and ${person.getname ()} are the same.

3. Assigning values to variables

In the first small point, a variable is defined, and the variable is assigned a value. For Velocity, a variable is a weak data type, and it can be assigned a number or array after assigning a String to the variable. You can assign the following six data types to a Velocity variable: A variable reference, a literal string, a property reference, a method reference, a literal number, an array list.

#set ($foo = $bar) #set ($foo = "Hello") #set ($foo. Name = $bar. Name) #set ($foo. Name = $bar. GetName ($arg)) #set ($foo = 123) #set ($foo = ["foo", $bar])

Second, the circulation

The syntax structure of a looping statement in Velocity is as follows:

#foreach ($element in $list) the is $element $velocityCount #end

The Velocity engine will loop the values in the list to the element variable, creating a $velocitycount variable as a count, starting with 1 and adding 1 for Each loop.

Third, conditional statements

The syntax for a conditional statement is as follows

#if (condition) ... #elseif (condition) ... #else ... #end

Iv. Relational operators

The Velocity engine provides the and, or, and not operators, respectively, for the &&, | | | And! For example:

#if ($foo && $bar) #end

Five, macro

A macro in Velocity can be understood as a function definition. The syntax for the definition is as follows:

#macro (macroName arg1 arg2 ...) ... #end

The syntax for calling this macro is:

#macroName (arg1 arg2 ...)

Here's a space between the arguments, and here's an example of defining and using Velocity macros:

#macro (SayHello $name) Hello $name #end#sayhello ("Velocity")

The result of the output is Hello Velocity

Vi. #parse and #include

The function of #parse and #include directives is to reference the file externally, and the difference is that #parse will refer to the content as similar to the source file, the content will be introduced in the place to parse, #include is to introduce the file as a resource file, The incoming content will be output intact as text. See the following examples:

FOO.VM file:

#set ($name = "velocity")

PARSE.VM:

#parse ("FOO.VM")

The output is: velocity

INCLUDE.VM:

#include ("FOO.VM")

The output is: #set ($name = "velocity")

The above includes some of the velocity's syntax, with detailed syntax for reference to Velocity's official documentation.

Back to top of page

Examples of automatically generated code

In the last example, we can generate arbitrary strings and print them, so why can't we generate some code that is defined in the established format and write to the file?

Here we have a real demo to complete this part of the content. The source code of the relevant content can refer to the attachment. This demo function is to achieve a student and teacher management, in fact, is a single-sheet maintenance. We want to be able to define only the model layer to generate all the code for MVC. In this demo, only the contents of the action and JSP are generated automatically, because there are many tools that can help us to automatically generate the code for both packages.

First, create a Java Web project in Eclipse, in an example to facilitate the management of the jar package, using MAVEN to build and manage the project. Build a good project directory structure as shown:

Figure 1. Project directory Structure

Java Resource in Java source code and resource files, Deployed resources in the web-related files. Using a Spring-like @Component and @Autowired annotations in a Java file to implement the IoC, MVC is implemented using annotations such as @Action, and JSTL is used in the JSP to output the page. In the catalogue shown, the four package annotation, filter, framework, and Util are the framework of this project and are not related to the business, similar to the functionality of spring and struts.

In the actual project we certainly want to be able to write a generic template file at the beginning, and then generate all the code at once, but often it is impossible, or more difficult. To solve this problem, we can write the velocity template file before writing the code according to the original process, temporarily forget the velocity. The code you write should be able to fully tune the content in one function that involves all levels of MVC. In this example, first write the Studentaction.java file, and the file shown in the WebApp directory. After writing the above code and running smoothly, we can write the template file according to the code we wrote earlier. Here, let's look at a sample of Java files and JSPs, respectively.

Listing 3. Actiontemplate.vm
#parse ("MACRO.VM") @Action ("${classnamelowcase}action") public class ${classnameupcase}action extends baseaction{@ autowired public ${classnameupcase}dao ${classnamelowcase}dao; Private list<${classnameupcase}> ${classnamelowcase}s; Private ${classnameupcase} ${classnamelowcase}; #foreach ($attr in ${attrs}) private ${attr[0]} ${attr[1]}; #end Public String ${classnamelowcase}list () {${classnamelowcase}s = ${classnamelowcase}dao.retrieveall${classnameupcase}s (); return "${classnamelowcase}list.jsp"; }  ...}

The above code shows some of the contents of a Java class converted to a VM template, please refer to the attachment for full content.

Some of the macros used are defined in the MACRO.VM file. The modification of the JSP is slightly more complicated than the Java file, because the value in the JSP using JSTL in request is also a syntax such as ${name}, so you want to output a string such as ${name} instead of being replaced by the template engine, you need to use an escape character, like this: \${name}.

To enable the table in this file to be reused, we take the table in this file separately and use the #parse command to include it. Here are the contents of LISTJSPTEMPLATE.VM and LISTTABLETEMPLATE.VM:

Listing 4. Listjsptemplate.vm
<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" UTF-8 "%><% @taglib prefix=" C "uri=" Http://java.sun.com/jsp/jstl/core "%><! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" "Http://www.w3.org/TR/html4/loose.dtd" >Listing 5. Listtabletemplate.vm
#parse ("MACRO.VM") #set ($plus = "status.index+1") <table border= "1" style= "width:100%" > <thead> <tr> <th>No.</th> #generateTH ($attrs) </tr> </thead> <tbody> <c:foreach var= "${ Classnamelowcase} "items=" ${${classnamelowcase}s} "varstatus=" status "> <tr ${classnamelowcase}id=" ${${ Classnamelowcase}.id} "> <td>${${plus}}</td> #generateTD ($classNameLowCase $attrs) <td> < Button class= "Modifybutton" >Modify</button> <button class= "DeleteButton" >Delete</button>< /td></tr> </c:forEach> </tbody></table>

After all the template files are defined, it is necessary to read the files and then set the model data type and name to the context according to these files, and finally write the parsed content to the appropriate directory. These work we put in a class called Velocitygenerator to do, its source code is as follows:

Listing 6. Templategenerator.java
public class Velocitygenerator {public static void main (string[] args) {velocityengine ve = new Velocityengine (); ve.se Tproperty (Runtimeconstants.resource_loader, "classpath");  Ve.setproperty ("Classpath.resource.loader.class", ClasspathResourceLoader.class.getName ()); Ve.init (); Template actiontpt = ve.gettemplate ("ACTIONTEMPLATE.VM"); Template listjsptpt = ve.gettemplate ("LISTJSPTEMPLATE.VM"); Template addtpt = ve.gettemplate ("ADDTEMPLATE.VM"); Template modifytpt = ve.gettemplate ("MODIFYTEMPLATE.VM");  Velocitycontext CTX = new Velocitycontext (); Ctx.put ("Classnamelowcase", "Teacher"); Ctx.put ("Classnameupcase", "Teacher"); String[][] Attrs = {{"Integer", "id"}, {"string", "name"}, {"string", "Serializeno"}, {"string", "Titile"}, {"String", " Subject "}}; Ctx.put ("Attrs", attrs); String RootPath = VelocityGenerator.class.getClassLoader (). GetResource (""). GetFile () + ". /.. /src/main "; Merge (actiontpt,ctx,rootpath+ "/java/com/liuxiang/velocity/action/teacheraction.java"); Merge (LISTJSPTPT,ctx,rootpath+ "/webapp/teacherlist.jsp"); Merge (addtpt,ctx,rootpath+ "/webapp/teacheradd.jsp"); Merge (modifytpt,ctx,rootpath+ "/webapp/teachermodify.jsp"); SYSTEM.OUT.PRINTLN ("Success ...");  private static void merge (template template, Velocitycontext ctx, String path) {PrintWriter writer = null; try {writer = New PrintWriter (path); Template.merge (CTX, writer); Writer.flush (); } catch (FileNotFoundException e) {e.printstacktrace ();} finally {writer.close ();}}}

After you run the above code, the Teacher-related code file will appear in the project folder.

There may not be many cases of this single table maintenance in the actual project, and the business logic and system architecture are more complex, and it is even more difficult to write template files. However, no matter how complex the system, the different business logic will have more or less similar code, especially in the JSP and JS display file, because we in a system requires the display style, the operation of the same time will inevitably have a similar content of the code appears. After summarizing these similarities, we can still use Velocity to help us generate some of the content's code, and even if there are some non-generic content, we can continue to modify in the generated code. Another benefit of using Velocity is that the generated code is better maintained and more unified in style.

Back to top of page

Conclusion

Velocity can be used in a variety of scenarios, this article is only one of its uses, it can also be applied to the MVC structure of the view layer, or dynamic content static and so on. In addition, Velocity is not the only template frame, the same excellent freemarker has been widely used, interested readers can go into more features and uses.

Quickly generate code using the Velocity template engine

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.