Recipe14.9.Integrating Struts and Velocity


Recipe 14.9. Integrating Struts and Velocity

Problem

You want to use a template engine for HTML page generation instead of JSPs in your Struts application.

Solution

Integrate the Velocity template engine into your Struts application, replacing your JSP pages with Velocity templates.

Discussion

The Velocity template engine (http://jakarta.apache.org/velocity) can create any kind of textual document by merging Java objects with a template. The template document contains special markup that Velocity parses and replaces with values from Java objects stored in a template context.

When you use Velocity with Struts, instead of forwarding to JSP pages, you forward to a Velocity template. The Velocity servlet services the request, processing the template through the Velocity template engine and returning the generated HTML as the response.

Here's an action, adapted from the Struts MailReader example, that forwards to a Velocity template to display the "Welcome" page:

<action    path="/WelcomeVel"            type="org.apache.struts.webapp.example.WelcomeAction">     <forward name="failure" path="/Error.jsp" />     <forward name="success" path="/welcome.vm" /> </action>

To use Velocity with Struts, you'll need to download the Velocity distribution from http://jakarta.apache.org/velocity. You also need to download the VelocityTools from http://jakarta.apache.org/velocity/tools/. VelocityTools includes helper classes that allow you to reference Struts-managed objects such as the action form and message resources. From the Velocity distribution, copy the velocity-1.4.jar and the velocity-dep-1.4.jar from the Velocity distribution directory to your application's WEB-INF/lib directory. For the VelocityTools /lib directory, copy the velocity-tools-1.1.jar, velocity-tools-generic-1.1.jar, velocity-tools-view-1.1.jar to your application's WEB-INF/lib directory.

Next, declare the Velocity view servlet and servlet mapping in your web.xml file. Traditionally, the .vm extension is used for Velocity templates. Example 14-26 shows the portion of a web.xml file that configure the Velocity servlet.

Example 14-26. VelocityViewServlet declaration and mapping
<!-- Velocity View Servlet --> <servlet>     <servlet-name>velocity</servlet-name>     <servlet-class>         org.apache.velocity.tools.view.servlet.VelocityViewServlet     </servlet-class>     <init-param>         <param-name>org.apache.velocity.toolbox</param-name>         <param-value>/WEB-INF/toolbox.xml</param-value>     </init-param>     <init-param>         <param-name>org.apache.velocity.properties</param-name>         <param-value>/WEB-INF/velocity.properties</param-value>     </init-param>     <load-on-startup>2</load-on-startup> </servlet> ... <!-- Map *.vm files to Velocity --> <servlet-mapping>     <servlet-name>velocity</servlet-name>     <url-pattern>*.vm</url-pattern> </servlet-mapping>

Velocity has the notion of a toolbox containing tools you can use in your templates. A tool is essentially a Java class you can reference by name. The /WEB-INF/toolbox.xml file, shown in Example 14-27, declares the Struts tools available to your templates.

Example 14-27. Toolbox containing the Velocity-Struts tools
<?xml version="1.0"?> <!--   Copyright 2003-2004 The Apache Software Foundation.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License.   $Id: ch14.xml,v 1.5 2005/03/21 18:08:10 kend Exp kend $ --> <toolbox>     <tool>         <key>math</key>         <scope>application</scope>         <class>org.apache.velocity.tools.generic.MathTool</class>     </tool>     <tool>         <key>link</key>         <class>org.apache.velocity.tools.struts.StrutsLinkTool</class>     </tool>     <!-- ordinarily the SecureLinkTool would simply replace the StrutsLinkTool          if SSL Ext. is in use - in that case the key would be 'link' but it's          'slink' here to distinguish between the two. -->     <tool>         <key>slink</key>         <class>org.apache.velocity.tools.struts.SecureLinkTool</class>     </tool>     <tool>         <key>text</key>         <class>org.apache.velocity.tools.struts.MessageTool</class>     </tool>     <tool>         <key>link</key>         <scope>request</scope>         <class>org.apache.velocity.tools.struts.StrutsLinkTool</class>     </tool>     <tool>         <key>errors</key>         <class>org.apache.velocity.tools.struts.ErrorsTool</class>     </tool>     <tool>         <key>messages</key>         <class>org.apache.velocity.tools.struts.ActionMessagesTool</class>     </tool>     <tool>         <key>text</key>         <scope>request</scope>         <class>org.apache.velocity.tools.struts.MessageTool</class>     </tool>          <tool>         <key>form</key>         <class>org.apache.velocity.tools.struts.FormTool</class>     </tool>     <tool>         <key>tiles</key>         <class>org.apache.velocity.tools.struts.TilesTool</class>     </tool>     <tool>         <key>validator</key>         <class>org.apache.velocity.tools.struts.ValidatorTool</class>     </tool> </toolbox>

For each tool, the key element specifies the name that the tool can be referenced by within your Velocity template. The /WEB-INF/velocity.properties contains general configuration information used by the Velocity view servlet. You can use these properties to control Velocity's log level and other settings.

#*  * Copyright 2003 The Apache Software Foundation.  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *     http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  *  * $Id: ch14.xml,v 1.5 2005/03/21 18:08:10 kend Exp kend $  *# #---------------------------------------------------------------------------- # These are the default properties for the # Velocity Runtime. These values are used when # Runtime.init( ) is called, and when Runtime.init(properties) # fails to find the specificed properties file. #---------------------------------------------------------------------------- #---------------------------------------------------------------------------- # R U N T I M E  L O G #---------------------------------------------------------------------------- # Velocity uses the Servlet APIs logging facilites. #---------------------------------------------------------------------------- # This controls if Runtime.error( ), info( ) and warn( ) messages include the # whole stack trace. The last property controls whether invalid references # are logged. #---------------------------------------------------------------------------- runtime.log.error.stacktrace = false runtime.log.warn.stacktrace = false runtime.log.info.stacktrace = false runtime.log.invalid.reference = true #---------------------------------------------------------------------------- # T E M P L A T E  E N C O D I N G #---------------------------------------------------------------------------- input.encoding=ISO-8859-1 output.encoding=ISO-8859-1 #---------------------------------------------------------------------------- # F O R E A C H  P R O P E R T I E S #---------------------------------------------------------------------------- # These properties control how the counter is accessed in the #foreach # directive. By default the reference $velocityCount will be available # in the body of the #foreach directive. The default starting value # for this reference is 1. #---------------------------------------------------------------------------- directive.foreach.counter.name = velocityCount directive.foreach.counter.initial.value = 1 #---------------------------------------------------------------------------- # I N C L U D E  P R O P E R T I E S #---------------------------------------------------------------------------- # These are the properties that governed the way #include'd content # is governed. #---------------------------------------------------------------------------- directive.include.output.errormsg.start = <!-- include error : directive.include.output.errormsg.end   =  see error log --> #---------------------------------------------------------------------------- # P A R S E  P R O P E R T I E S #---------------------------------------------------------------------------- directive.parse.max.depth = 10 #---------------------------------------------------------------------------- # VELOCIMACRO PROPERTIES #---------------------------------------------------------------------------- # global : name of default global library.  It is expected to be in the regular # template path.  You may remove it (either the file or this property) if # you wish with no harm. #---------------------------------------------------------------------------- #dev-changes by Marino webapp.resource.loader.cache = false velocimacro.library.autoreload = true velocimacro.library = /WEB-INF/VM_global_library.vm,/WEB-INF/                       Validator_library.vm velocimacro.permissions.allow.inline = true velocimacro.permissions.allow.inline.to.replace.global = false velocimacro.permissions.allow.inline.local.scope = false velocimacro.context.localscope = false #---------------------------------------------------------------------------- # INTERPOLATION #---------------------------------------------------------------------------- # turn off and on interpolation of references and directives in string # literals.  ON by default :) #---------------------------------------------------------------------------- runtime.interpolate.string.literals = true #---------------------------------------------------------------------------- # RESOURCE MANAGEMENT #---------------------------------------------------------------------------- # Allows alternative ResourceManager and ResourceCache implementations # to be plugged in. #---------------------------------------------------------------------------- resource.manager.class = org.apache.velocity.runtime.resource. ResourceManagerImpl resource.manager.cache.class = org.apache.velocity.runtime.resource. ResourceCacheImp

Now, you create the Velocity template itself. Suppose you wanted to replace a JSP page with an equivalent Velocity template. Example 14-28 shows the welcome.jsp page from the Struts MailReader application.

Example 14-28. Welcome page from the Struts example application
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="/tags/struts-bean" prefix="bean" %> <%@ taglib uri="/tags/struts-html" prefix="html" %> <html> <head> <title><bean:message key="index.title"/></title> <link rel="stylesheet" type="text/css" href="base.css" /> </head> <h3><bean:message key="index.heading"/></h3> <ul> <li><html:link action="/EditRegistration?action=Create"> <bean:message key="index.registration"/></html:link></li> <li><html:link action="/Logon"><bean:message key="index.logon"/> </html:link></li> </ul> <h3>Language Options</h3> <ul> <li><html:link action="/Locale?language=en">English</html:link></li> <li><html:link action="/Locale?language=ja" useLocalEncoding="true"> Japanese</html:link></li> <li><html:link action="/Locale?language=ru"  </ul> <hr /> <p><html:img bundle="alternate" pageKey="struts.logo.path"  altKey="struts.logo.alt"/></p> <p><html:link action="/Tour"><bean:message key="index.tour"/></html:link></p> </body> </html>

Example 14-29 shows this same page implemented as a Velocity template (welcome.vm).

Example 14-29. Welcome page implemented as a Velocity template
#*  * These are comments and will be ignored by the Velocity engine.  *# <html> <head> <title>$text.get("index.title")</title> <link rel="stylesheet" type="text/css" href="base.css" /> </head> <h3>$text.get("index.heading")</h3> <ul> <li>     <a href="$link.setAction('/EditRegistration').                 addQueryData('action','Create')">         $text.get("index.registration")     </a> <li>     <a href="$link.setAction('/Logon')">         $text.get("index.logon")     </a> </ul> <h3>Language Options</h3> <ul> <li><a href="$link.setAction('/Locale').addQueryData('language','en')"> English</a></li> <li><a href="$link.setAction('/Locale').addQueryData('language','ja')"> Japanese</a></li> <li><a href="$link.setAction('/Locale').addQueryData('language','ru')"> Russian</a></li> </ul> <hr /> <p><a href="$link.setAction('/Tour')">$text.get("index.tour")</a></p> </body> </html>

When you build and deploy this modified Struts MailReader application, you'll see that this page looks and behaves exactly as it does when implemented as a JSP page, and no changes had to be made to any Struts actions or action forms.

See Also

The Velocity project site is located at http://jakarta.apache.org/velocity. From here, you can download Velocity and the VelocityTools used in this recipe. You'll also find several essays that compare Velocity to JSP and other page-generation technologies.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net