Recipe2.3.Using Constants on JSPs


Recipe 2.3. Using Constants on JSPs

Problem

Without resorting to scriptlets, you want to use application constantspublic static fields defined in Java classeson a JSP page.

Solution

Use the bind tag provided by the Jakarta Taglibs unstandard tag library to create a JSTL variable containing the value of the constant field:

<%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %> <un:bind var="constantValue"         type="com.foo.MyClass"        field="SOME_CONSTANT"/> <bean:write name="constantValue"/>

Discussion

A lot of teams put hard work into avoiding hard-coded String literals in their Java classes by using public static fields (constants). Unfortunately, neither Struts nor JSP provide a means to access these constants from a JSP page without resorting to JSP scriptlet like the following:

<%= com.foo.MyClass.SOME_CONSTANT %>

However, many development teams ban, or at least frown on scriptlet use on JSP pages.

Scriptlets (<% . . . %>) and runtime expressions (<%= . . . %>) place Java code directly onto a JSP page. They are not inherently evil, but they can lead your development down a slippery slope by turning your JSP pages into a tangled brittle mass of intermixed HTML, JSP, and Java code. Find solutions that don't require you to use scriptlets. You'll findparticularly with the introduction of JSTLthat you can always find a way around the dreaded scriptlet.


The Solution provides a way around this quandary through the use of a custom JSP tag, the un:bind tag. This tag is part of the unstandard tag library, part of the Jakarta Taglibs distribution. The unstandard tag library contains custom JSP tags that have been or are being considered for use in the standard tab library. The standard tag library is the Jakarta Taglibs implementation of the JSTL specification.

The unstandard tag library can be downloaded from http://cvs.apache.org/builds/jakarta-taglibs-sandbox/nightly/projects/unstandard/. To use the library, copy the unstandard.jar and unstandard.tld files into your web applications WEB-INF/lib directory.

The un:bind tag provides a means for creating a JSP page context variable, which references a field of any Java class. The fields can be instance variables or static variables. Most well-designed Java classes don't expose instance variables as public fields, yet many expose static variables as public fields.

You can put the Solution to work by creating a simple JSP page that uses some of the static fields provided by Struts. Since Struts 1.1, the constants used by Struts are kept in the class org.apache.struts.Globals. The values of these constants specify the key values under which various Struts-related entities are stored in the request, session, or application context. The JSP page in Example 2-5 uses the un:bind tag to show one of these values.

Example 2-5. Using bind to access Struts globals
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head>   <title>Struts Cookbook - Chapter 4 : Using Bind</title> </head> <body>   <un:bind var="servletKey"           type="org.apache.struts.Globals"          field="SERVLET_KEY"/>   <p>   Field name: SERVLET_KEY<br />   Field value: <bean:write name="servletKey"/>< br />   Attribute Value: <c:out value="${applicationScope[servletKey]}"/>< br />   </p> </body> </html>

This page uses un:bind to retrieve the value of the SERVLET_KEY field from the Struts Globals class. The value of the SERVLET_KEY field is used as the servlet context attributes key under which the mapping (e.g. /action/* or *.do) defined for the Struts controller servlet is stored.

The un:bind tag is good to use when you need to access constants on an ad hoc basis. However, it is fairly verbose since you need to use the un:bind tag first to create the variable, and then the bean:write or c:out tag to render the value. Imagine the size of a JSP page showing all of the constants from the Globals classthere are 17 constants in all! Many applications rely heavily on constants and may have several classes, each containing dozens of these fields. Requiring the use of a separate tag for every single use of a constant can be cumbersome.

You can use an alternative solution, albeit one requiring some additional Java coding, by binding the constants into a Map property of a JavaBean. You store the bean in the servlet context. You can then access the values directly using the bean:write and c:out tags. The Constants class in Example 2-6 defines a JavaBean containing a map of the constants from the Struts Globals class. The ConstantsPlugin in Example 2-7 loads an instance of Constants into the servlet context.

Example 2-6. JavaBean holding constants from Struts Globals
package com.oreilly.strutsckbk.ch04; import java.util.HashMap; import java.util.Map; import org.apache.struts.Globals; public class Constants {     private Map strutsGlobals;          public Constants( ) {         strutsGlobals = new HashMap( );         strutsGlobals.put( "ACTION_SERVLET_KEY",                             Globals.ACTION_SERVLET_KEY );         strutsGlobals.put( "SERVLET_KEY", Globals.SERVLET_KEY );     }          public Map getStrutsGlobals( ) {         return strutsGlobals;     }     public void setStrutsGlobals(Map strutsGlobals) {         this.strutsGlobals = strutsGlobals;     } }

Example 2-7. Plug-in that loads Constants into the servlet context
package com.oreilly.strutsckbk.ch04; import javax.servlet.ServletException; import org.apache.struts.action.ActionServlet; import org.apache.struts.action.PlugIn; import org.apache.struts.config.ModuleConfig; public class ConstantsPlugin implements PlugIn {     public void destroy( ) {     }     public void init(ActionServlet servlet, ModuleConfig module)             throws ServletException {         Constants constants = new Constants( );         servlet.getServletContext( ).setAttribute("Constants", constants);     } }

Example 2-8 (globals_test.jsp) shows a JSP page that accesses and displays values loaded by the ConstantsPlugin. The first constant is rendered using the Struts bean:write tag and the second using the JSTL c:out tag.

Example 2-8. Accessing constants using Struts and JSTL
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <html> <head>   <title>Struts Cookbook - Chapter 4 : Accessing Constants</title> </head> <body>   <p>   Field name: ACTION_SERVLET_KEY<br />   Field value: <bean:write name="Constants"                         property="strutsGlobals(ACTION_SERVLET_KEY)"/><br />   </p>   <p>   Field name: SERVLET_KEY<br />   Field value: <c:out value="${Constants.strutsGlobals.SERVLET_KEY}"/><br />   </p> </body> </html>

The greatest drawback to this approach is that you manually have to create the map to hold the values. If a new constant is added to a class, you will have to change the source for the Constants class to retrieve it.

See Also

All details on the Jakarta Taglibs project can be found at http://jakarta.apache.org/taglibs. Recipe 5-4 provides details on accessing maps from Struts and JSTL. Struts plug-ins are discussed in Recipe 2.1.

Kris Schneider built a JavaBean similar to the Constants class of Example 2-6 that uses reflection to access the public static variables of any specified class. The source is available from the archived struts-user mailing list discussion at http://marc.theaimsgroup.com/?l=struts-user&m=108929374300664&w=2.



    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