blob: 0b17039d6c6303fef8a9b3494c6096dd555c72f3 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Apache Velocity - Getting Started with a Web Application</title>
<style type="text/css" media="all">
@import url("./css/maven-base.css");
@import url("./css/maven-theme.css");
@import url("./css/site.css");
</style>
<link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
<link rel="alternate" href="http://feeds.feedburner.com/ApacheVelocitySiteNews" type="application/rss+xml" title="Apache Velocity - Getting Started with a Web Application News" />
<meta name="author" content="Velocity Documentation Team" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body class="composite">
<div id="banner">
<a href="../../../" id="bannerLeft">
<img src="images/velocity_project_wide.png" alt="" />
</a>
<span id="bannerRight">
<img src="images/velocity-logo.png" alt="" />
</span>
<div class="clear">
<hr/>
</div>
</div>
<div id="breadcrumbs">
<div class="xleft">
<a href="http://www.apache.org/">Apache</a>
&gt;
<a href="../../../">Velocity</a>
&gt;
Velocity Engine
</div>
<div class="xright"> <a href="../../devel/">Engine</a>
|
<a href="../../../tools/devel/">Tools</a>
|
<a href="../../../anakia/devel/">Anakia</a>
|
<a href="../../../texen/devel/">Texen</a>
|
<a href="../../../docbook/">DocBook</a>
|
<a href="../../../dvsl/devel/">DVSL</a>
</div>
<div class="clear">
<hr/>
</div>
</div>
<div id="leftColumn">
<div id="navcolumn">
<h5>Velocity</h5>
<ul>
<li class="none">
<a href="index.html">General</a>
</li>
<li class="none">
<a href="overview.html">Overview</a>
</li>
<li class="none">
<a href="getting-started.html">Getting Started</a>
</li>
<li class="none">
<strong>Web Applications</strong>
</li>
<li class="none">
<a href="../../../download.cgi">Download</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/VelocityFAQ">FAQ (Wiki)</a>
</li>
</ul>
<h5>Docs</h5>
<ul>
<li class="none">
<a href="user-guide.html">User Guide</a>
</li>
<li class="none">
<a href="developer-guide.html">Developer Guide</a>
</li>
<li class="none">
<a href="vtl-reference-guide.html">VTL Reference</a>
</li>
<li class="none">
<a href="glossary.html">Glossary</a>
</li>
</ul>
<h5>Developers</h5>
<ul>
<li class="none">
<a href="license.html">License</a>
</li>
<li class="none">
<a href="apidocs/index.html">Javadoc</a>
</li>
<li class="none">
<a href="changes-report.html">Changes</a>
</li>
<li class="none">
<a href="jira-report.html">Resolved Issues</a>
</li>
<li class="none">
<a href="upgrading.html">Upgrading</a>
</li>
<li class="none">
<a href="jar-dependencies.html">Dependencies</a>
</li>
<li class="none">
<a href="http://svn.apache.org/viewvc/velocity/engine/trunk/">Source Code Repository</a>
</li>
<li class="none">
<a href="build.html">Building from Source</a>
</li>
</ul>
<h5>Community</h5>
<ul>
<li class="none">
<a href="http://wiki.apache.org/velocity/">Wiki</a>
</li>
<li class="none">
<a href="../../../news.html">Recent News</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/PoweredByVelocity">Powered By Velocity</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/VelocityEditors">IDE/Editor Plugins</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/PublishedArticlesAndBooks">Articles and Books</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/GetInvolved">Get Involved</a>
</li>
<li class="none">
<a href="../../../contact.html">Mailing Lists</a>
</li>
</ul>
<h5>Velocity Development</h5>
<ul>
<li class="none">
<a href="http://wiki.apache.org/velocity/RoadMap">Road Map</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/CodeStandards">Coding Standards</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/DocumentationGuidelines">Documentation Guidelines</a>
</li>
<li class="none">
<a href="https://issues.apache.org/jira/browse/VELOCITY">Issues</a>
</li>
<li class="none">
<a href="../../../who-we-are.html">Who we are</a>
</li>
</ul>
<h5>Translations</h5>
<ul>
<li class="none">
<a href="http://www.jajakarta.org/velocity/">Site (Japanese)</a>
</li>
<li class="none">
<a href="translations/user-guide_fi.html">User's Guide (Finnish)</a>
</li>
<li class="none">
<a href="translations/user-guide_fr.html">User's Guide (French)</a>
</li>
<li class="none">
<a href="translations/user-guide_es.html">User's Guide (Spanish)</a>
</li>
</ul>
<h5>Project Documentation</h5>
<ul>
<li class="collapsed">
<a href="project-info.html">Project Information</a>
</li>
<li class="collapsed">
<a href="project-reports.html">Project Reports</a>
</li>
</ul>
<a class="poweredBy" href="../../../" title="Apache Velocity" ><img class="poweredBy" alt="Apache Velocity" src="images/pbv90x30.png" /></a>
<a class="poweredBy" href="../../../rss/news.rss" title="Velocity News Feed" ><img class="poweredBy" alt="Velocity News Feed" src="images/feed-icon-24x24.jpg" /></a>
<iframe src="http://www.apache.org/ads/buttonbar.html"
style="border-width:0; float: left" frameborder="0" scrolling="no"
width="135"
height="265" ></iframe>
</div>
</div>
<div id="bodyColumn">
<div id="contentBox">
<div class="section"><h2><a name="Building_a_Web_Application_with_Velocity"></a>
Building a Web Application with Velocity</h2>
<p>
Velocity is often used to generate web pages in applications, usually as a direct replacement
for JSP. Some of the benefits of using Velocity to generate web pages are:
</p>
<ul><li><strong>Simplicity</strong> - The pages can be written and maintained by non-technical web designers.
</li>
<li><strong>Ease of maintainance</strong> - Scripting is removed from web pages with the recommended MVC approach.
</li>
<li><strong>Access both methods and properties</strong> - Web designers can reference methods as well as properties of objects in a context.
</li>
<li><strong>Consistency</strong> - Velocity can be used for other text generation tasks (such as sending email)
providing a consistent way to mark up text.
</li>
</ul>
<p>This document provides some basic info on getting started with Velocity in a web application.
</p>
</div>
<div class="section"><h2><a name="Use_a_Framework"></a>
Use a Framework</h2>
<p>
The primary purpose of the Velocity engine is simply to generate text based on
a template. Consequently, Velocity does not contain any web-related functionality in and of itself.
To make a web application, you will need a framework to respond to HTTP requests,
handle user authentication, make business logic calls, and generate a response.
There are several strong contenders.
</p>
<ol type="1"><li><strong>Velocity Tools / VelocityViewServlet</strong> -
The easiest way to get started is to download the companion <a href="http://velocity.apache.org/tools/devel/" class="externalLink">Velocity Tools</a>
subproject and use the
<a href="http://velocity.apache.org/tools/devel/view/" class="externalLink">VelocityViewServlet</a>
. This servlet is easy to configure
and install. You create a directory of templates on your web server, edit an XML file that lists various &quot;Tools&quot; to
place in the context and you are off. More details can be found in the tutorial below.
</li>
<li><strong>Velocity Tools / VelocityStruts</strong> -
You may be familiar with the popular <a href="http://struts.apache.org/" class="externalLink">Struts</a>
framework, originally designed to provide much needed
application functionality to JSP. With the <a href="http://velocity.apache.org/tools/devel/struts/" class="externalLink">VelocityStruts</a>
module of Velocity Tools you can substitute Velocity for JSP as the page template language. This allows you
to take advantage of the large base of Struts infrastructure while designing pages using Velocity.
</li>
<li><strong>Third party frameworks</strong> - There are a number of third party frameworks listed on the
<a href="http://wiki.apache.org/velocity/PoweredByVelocity" class="externalLink">PoweredByVelocity</a>
wiki page. Of these, <a href="http://www.springframework.org/" class="externalLink">Spring</a>
is probably the most sophisticated and well known.
<a href="http://jakarta.apache.org/turbine/" class="externalLink">Jakarta Turbine</a>
has many features and can also be very useful.
It was built with Velocity as the primary page language, which is not surprising since many of the original Velocity
developers were involved in creating it.
Simpler alternative are the <a href="http://click.sourceforge.net/" class="externalLink">Click</a>
or <a href="http://mav.sourceforge.net/" class="externalLink">Maverick</a>
frameworks,
which provide a simple Controller architecture that integrates nicely with
Velocity.
</li>
<li><strong>Build your own</strong> - A final alternative is to build your own framework. Create a dispatcher servlet,
retrieve templates from a file or database, integate with your business logic and send the results back to the user.
Often you'll have an easier time starting with one of the existing frameworks
and customizing it. In particular you can add new functionality to the VelocityViewServlet simply by creating a subclass.
</li>
</ol>
<p>
As a side note, you may also come across references to VelocityServlet, which is a deprecated servlet that was included in
the Velocity Engine up to version 1.4. Since VelocityServlet is no longer being maintained we strongly recommend
you use VelocityViewServlet in Velocity Tools instead.
</p>
</div>
<div class="section"><h2><a name="Web-Specific_Issues"></a>
Web-Specific Issues</h2>
<p>
There are a few issues with Velocity that are specific to web applications. Here is a brief discussion of the most
commonly encountered issues.
</p>
<div class="section"><h3><a name="Changing_Object_State_-_Dont"></a>
Changing Object State - Don't!</h3>
<p>Velocity provides the ability to call any method of an object acting as a reference. This can be useful when displaying
information into the page but is dangerous when object or application state is modified.
</p>
<p>
For example,
the following code safely calls the size() method of a list and displays the result.
</p>
<div class="source"><pre>
There are $users.size() currently logged in.
</pre>
</div>
<p>
An example of an unsafe operation concerns a financial web page with an object in the context that calculates
data year by year. The method calculateNextYear() calculates data for the next year and advances an internal counter:
</p>
<div class="source"><pre>
2005 data: $table.data
$table.calculateNextYear()
2006 data: $table.data
</pre>
</div>
<p>The problem with this approach is that the code cannot be repeated in multiple parts of the page. You may not intend
to do so, but it's easy to forget this when cutting and pasting or writing control statements (such as #if or #foreach).
This becomes more of an issue when you are dealing with application or session-level state.
</p>
<p>The (strongly) recommended practice is
to only use Velocity for inserting information into text. Method calls can be useful to retrieve information. However, it's generally a bad idea
to use a method call to change object state, and it's always a bad idea to change application state.
</p>
<p>If you find yourself needing to change object state (as in the previous example) try precalculating all the possible
values in the controller and putting them in a List or Map. Any changes to application state should always be
done by the controller.
</p>
<p>On a related note, you should always put a List or Set into the context instead of an Iterator or Enumeration. This allows the collection to
be used more than once in the page with no change in behavior.
</p>
</div>
<div class="section"><h3><a name="Escaping_HTMLXML_Entities"></a>
Escaping HTML/XML Entities</h3>
<p>
Any user-entered text that contains special HTML or XML entities (such as &lt;, &gt;, or &amp;) needs to be escaped
before included in the web page. This is required, both to ensure the text is visible, and also to prevent
dangerous <a href="http://en.wikipedia.org/wiki/Cross_site_scripting" class="externalLink">cross-site scripting</a>
.
Unlike, for example, JSTL (the Java Standard Tag Language found in Java Server Pages),
Velocity does not escape references by default.
</p>
<p>However, Velocity provides the ability to specify a <code>ReferenceInsertionEventHandler</code>
which will alter the value of a reference before it is inserted into the page.
Specifically, you can configure the <code>EscapeHtmlReference</code>
handler into your <code>velocity.properties</code> file to escape all
references (optionally) matching a regular expression.
The following example will escape HTML entities in any reference that starts with
&quot;msg&quot; (e.g. <code>$msgText</code>).
</p>
<blockquote><pre>eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeHtmlReference
eventhandler.escape.html.match = /msg.*/
</pre></blockquote><p>
Note that other kinds of escaping are sometimes required. For example, in style sheets the @ character needs
to be escaped, and in Javascript strings the single apostrophe ' needs to be escaped.
</p>
</div>
<div class="section"><h3><a name="Securing_the_Application"></a>
Securing the Application</h3>
<p>
Since a web application is running on a central server, that typically has multiple users and confidential resources,
care must be taken to make certain that the web application is secure. Most standard web security principles apply to a
web application built with Velocity. A few specific issues (such as system configuration, more on cross-site scripting,
and method introspection) are written up in this article on
<a href="http://wiki.apache.org/velocity/BuildingSecureWebApplications" class="externalLink">Building Secure Applications with Velocity</a>
.
In particular, you may want to prevent template designers from including &quot;dangerous&quot; reflection-related methods
by specifying the <code>SecureUberspector</code> to get/set properties and execute method calls.
</p>
<blockquote><pre>runtime.introspector.uberspect = org.apache.velocity.util.introspection.SecureUberspector
</pre></blockquote></div>
<div class="section"><h3><a name="Log_Files"></a>
Log Files</h3>
<p>
A minor point is that (in some circumstances) Velocity, in the absence of any log-related configuration, creates a log file in the current directory.
When Velocity is used in a web application the &quot;current directory&quot; is usually the current directory from which the application
server is started. If you start seeing the file &quot;velocity.log&quot; files in random places on your server filesystem, check
the Velocity log configuration. This is due to the default use of the Avalon Log Kit when present in the classpath.
Typically this occurs when Velocity is used within a web application outside of web page generation (e.g. for sending email).
To solve this problem, remove any file labeled &quot;avalon-logkit&quot; from the classpath or properly configure the log file location.
</p>
</div>
</div>
<div class="section"><h2><a name="Tutorial"></a>
Tutorial</h2>
<p>
What follows is a brief tutorial on building a simple web app with VelocityViewServlet. Note that it
suggests you compile VelocityViewServlet from the source. This isn't actually required to use
VelocityViewServlet but we recommend it in this case in order to see the source and then
compile the example files.
</p>
<p>Prerequisites for doing the following include the Java Developer's Kit (JDK) and
<a href="http://ant.apache.org/" class="externalLink">Apache Ant</a>
.
</p>
<p>
For more information, consult the
<a href="http://velocity.apache.org/tools/devel/" class="externalLink">Velocity Tools</a>
documentation.
</p>
<ol type="1"><li>Download the Velocity Tools project source (you need the source for the examples)
from the <a href="http://velocity.apache.org/download.cgi#tools" class="externalLink">download page</a>
.
</li>
<li> Build the Velocity Tools jar and the &quot;simple&quot; example by typing:
<div class="source"><pre>
ant example.simple
</pre>
</div>
</li>
<li>Take a look at the &quot;examples&quot; directory. You will see a file &quot;index.vm&quot;. Here's an excerpt:
<div class="source"><pre>
&lt;html&gt;
&lt;body&gt;
I'm a velocity template.
#if( $XHTML )
#set( $br = &quot;&lt;br /&gt;&quot; )
#else
#set( $br = &quot;&lt;br&gt;&quot; )
#end
$br
$br
Here we use a custom tool: $toytool.message
$br
$br
Here we get the date from the DateTool: $date.medium
&lt;/body&gt;
&lt;/html&gt;
</pre>
</div>
You can copy any additional velocity files
into this same directory. In examples/WEB-INF you will see a file &quot;toolbox.xml&quot;. This specifies a list of &quot;Tools&quot;
that are automatically included in the context.
<div class="source"><pre>
&lt;toolbox&gt;
&lt;xhtml&gt;true&lt;/xhtml&gt;
&lt;tool&gt;
&lt;key&gt;toytool&lt;/key&gt;
&lt;class&gt;ToyTool&lt;/class&gt;
&lt;/tool&gt;
&lt;data type=&quot;number&quot;&gt;
&lt;key&gt;version&lt;/key&gt;
&lt;value&gt;1.1&lt;/value&gt;
&lt;/data&gt;
&lt;data type=&quot;boolean&quot;&gt;
&lt;key&gt;isSimple&lt;/key&gt;
&lt;value&gt;true&lt;/value&gt;
&lt;/data&gt;
&lt;data type=&quot;string&quot;&gt;
&lt;key&gt;foo&lt;/key&gt;
&lt;value&gt;this is foo.&lt;/value&gt;
&lt;/data&gt;
&lt;data type=&quot;string&quot;&gt;
&lt;key&gt;bar&lt;/key&gt;
&lt;value&gt;this is bar.&lt;/value&gt;
&lt;/data&gt;
&lt;tool&gt;
&lt;key&gt;map&lt;/key&gt;
&lt;class&gt;java.util.HashMap&lt;/class&gt;
&lt;/tool&gt;
&lt;tool&gt;
&lt;key&gt;date&lt;/key&gt;
&lt;scope&gt;application&lt;/scope&gt;
&lt;class&gt;org.apache.velocity.tools.generic.DateTool&lt;/class&gt;
&lt;/tool&gt;
&lt;/toolbox&gt;
</pre>
</div>
And finally the web.xml file specifies the name of the servlet and location of toolbox.properties.
<div class="source"><pre>
&lt;web-app&gt;
&lt;servlet&gt;
&lt;servlet-name&gt;velocity&lt;/servlet-name&gt;
&lt;servlet-class&gt;
org.apache.velocity.tools.view.servlet.VelocityViewServlet
&lt;/servlet-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;org.apache.velocity.toolbox&lt;/param-name&gt;
&lt;param-value&gt;/WEB-INF/toolbox.xml&lt;/param-value&gt;
&lt;/init-param&gt;
&lt;load-on-startup&gt;10&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;velocity&lt;/servlet-name&gt;
&lt;url-pattern&gt;*.vm&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;welcome-file-list&gt;
&lt;welcome-file&gt;index.vm&lt;/welcome-file&gt;
&lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</pre>
</div>
</li>
<li>Copy this directory into your &quot;webapps&quot; directory on Tomcat. You could also copy &quot;simple.war&quot;, but copying in the entire directory
will let you experiment with changes. You should now be able to access your simple one-page webapp with this URL. (or something similar):
<div class="source"><pre>
http://localhost:8080/simple/index.vm
</pre>
</div>
</li>
<li>Experiment with adding new Velocity pages. Note that you can access any velocity page just by changing the URL. Try changing the
entries in toolbox.xml or creating your own tools. Consult the <a href="http://velocity.apache.org/tools/devel/" class="externalLink">Velocity Tools</a>
documentation and the <a href="http://wiki.apache.org/velocity/" class="externalLink">Wiki</a>
for more info on the wide variety of tools available.
</li>
</ol>
</div>
</div>
</div>
<div class="clear">
<hr/>
</div>
<div id="footer">
<div class="xright">&#169;
2000-2008
The Apache Software Foundation
Last Published: 2008-12-01 08:05:38
</div>
<div class="clear">
<hr/>
</div>
</div>
</body>
</html>