Since my article "JSP Best Practices" first appeared in JavaWorld in late 2001, the use of JavaServer Pages (JSP) technology has grown dramatically. Numerous tools now make Webpage development with JSP technology easier than ever. The best practices I recommended in my previous article still apply. With new available features, tools, and JSP development ideas, however, you may employ several additional best practices for even smoother development of highly maintainable JSP-based applications. This article outlines some best practices that utilize the most significant new features, tools, and ideas:
- Begin writing JSP documents
- Employ JSP code conventions
- Use the appropriate scope
- Carefully manage session scope
- Take advantage of JavaServer Pages Standard Tag Library (JSTL)
- Take advantage of servlet filters (Intercepting Filter pattern)
- Document the "APIs" of your JSP pages and documents
- Precompile your JSP pages and documents
- Organize your files and directories for easy development and deployment
- Carefully consider using proprietary, vendor-specific features
- Use Extensible Hypertext Markup Language (XHTML) syntax for HTML tags
Begin writing JSP documents rather than JSP pages
The JSP specification supports JSP pages as well as JSP documents. The main differentiator between the two is their level of XML compliance. JSP pages use the traditional or "shorthand" syntax, while JSP documents are completely XML-compliant. JSP documents are sometimes referred to as "JSP pages using XML syntax," but I will distinguish them here as JSP pages and JSP documents.
I prefer JSP documents for several reasons including:
- You can easily verify JSP documents as well-formed XML/HTML.
- You can validate JSP documents against an XML Schema.
- You can readily write and parse JSP documents using standard XML tools.
- You can readily write or present JSP documents in alternate forms using XSLT (Extensible Stylesheet Language Transformations). See the "JSP Documentation with XSLT" sidebar for an example.
- JSP uses XML-compliant include and forward actions, as well as custom tags, so making the entire document XML-compliant leads to increased code consistency.
- JSP documents require slightly more developer discipline than JSP pages, but your reward is more readable and maintainable documents, especially if you are new to JSP.
See "Writing JSPs in XML Using JSP 1.2" for more information on creating JSP documents and their advantages.
One significant disadvantage of JSP documents is that no XML-compliant version of JSP comments exists. A JSP document developer can use client-side (HTML-/XML-style) comments or embed Java comments in scriptlets, but there is no JSP document equivalent to
<%-- -->. This is a disadvantage because the other two commenting styles JSP documents can use have their own drawbacks. You can see the client-side comments in the rendered page using the browser's View Source option. The Java comments in scriptlets require placing Java code directly in the JSP document.
Throughout the rest of this article, I refer generically to JSPs to imply both JSP pages and JSP documents, because the best practices I discuss generally apply to both JSP types.
Employ JSP code conventions
It is prudent on any project, using any language, to follow coding standards and conventions to improve development, maintenance, and testing of your software. Reading another developer's code is often neither simple nor enjoyable. Conversely, if all developers followed the same naming and other conventions, code review and maintenance would be easier for everyone involved, including the original developer.
Sun Microsystems has recently assisted organizations trying to create these conventions by making the document "Code Conventions for the JavaServer Pages Technology Version 1.x Language" freely available (see Resources). If your organization does not already follow JSP code conventions, I recommend using this document as a starting point. You can either use it as-is or build your own conventions around it.
Use appropriate scope for bound objects
The JSP specification supports four levels of scope (application, session, request, and page) that you can associate with objects created explicitly for JSPs to use. Because objects bound to any of these four scopes consume memory and, in some cases, require cleanup, it is best to use the appropriate scope for the task you want to accomplish.
Application scope is the broadest scope and should only be used when necessary. You can create objects bound at application level in JSPs that are not session-aware, so application scope is useful for storing information when using these types of JSPs. You can also use application-bound objects to share data among different sessions of the same application. When you no longer need objects bound to an application, you should explicitly remove them to free up memory resources.
In my experience, session scope is more commonly used than application scope. Session scope allows you to create and bind objects to a session. You must create objects bound to the session in session-aware JSPs and make them available to all JSPs and servlets in the same session. Session scope is often used for managing security credentials and for managing state among multiple pages (such as in a Web-based wizard). As with application scope, objects bound to session scope should be explicitly removed when no longer needed. Also, I typically make classes serializable if I intend to bind their instantiations to the session scope.
I use request scope most often for binding created objects. Objects created and bound to request scope are available to pages in that same request. These objects are automatically released from memory when request processing completes. This is advantageous because explicit cleanup is not required and there is less risk of burdening the system with needless memory consumption.
You should use page scope for objects created only for the current page. Like request scope, the page scope does not require explicit removal of created and bound objects. I rarely use page scope in my JSP applications, but it is the
<jsp:useBean> action's default scope.
Which scope to use?
You should carefully choose scope for created objects to ensure efficient memory use and management. In general, I typically begin with request scope in my designs and then evaluate whether I need a broader scope for my created objects.
Carefully manage session scope
As stated in the best practice above, use session scope only when necessary and be sure to explicitly remove objects from session scope when you no longer require session access to these objects. For any JSP in which you don't use a session-bound object, you can set the page directive's session attribute to false to avoid the overhead involved with session management. However, I find few Web applications that don't need session support. Instead, I typically use session support for security mechanisms and other Web application needs. Even though a session expires after a configurable amount of time, it is best to invalidate these sessions explicitly when you no longer need them rather than rely exclusively on the automatic timeout mechanism.
Take advantage of JSTL
One of the most significant advancements for JSP developers has been the introduction and adoption of JSTL. Normally referred to as JSTL, it is also referred to as JSP Standard Tag Library. Note the T in JSTL stands for Tag rather than Template.
JSTL: A brief background and overview
In my earlier article, I recommended that JSP developers use available custom tag libraries rather than reinvent the wheel. Many commercial and open source custom tag libraries are available, but their one drawback requires developers to write JSPs to use those libraries in ways mandated by those custom tags. The advent of JSTL has addressed this downside by providing standard interfaces to the custom tags that perform many basic functions JSP developers need. Different vendors might implement the JSTL tags differently, but developers don't need to know about the differences in implementation. If a JSP developer writes his pages or documents to use JSTL tags, the JSP page or document should work with any JSTL implementation.
Plenty of good books and online resources exist for learning about JSTL (see Resources). Here, I briefly touch on JSTL's general advantages and features.
In short, JSTL offers all the benefits of any publicly available custom tag library, but also provides the additional benefit of a standardized tag API. JSTL facilitates highly maintainable and transferable pages or documents. I list JSTL's specific advantages:
- JSTL allows for tag-based iteration, conditionals, and other functionality previously implemented with Java scriptlets embedded directly in the JSP either with homegrown custom tags, a nonstandard tag library, or by abandoning the JSP in favor of a servlet.
- JSTL tag interfaces (tag name, optional and required attributes, etc.) are standardized so that, once written, JSPs using these tags should work with any JSTL tag implementation.
- JSTL takes advantage of expression language (EL) syntax.
- Writing custom tags requires more effort and experience than many JSP development tasks. JSTL addresses this in two ways: First, as mentioned above, JSTL handles many common needs for custom tags. Second, JSTL provides mechanisms that make writing your own custom tags easier, especially if you want your own custom tag libraries to support the EL.
Specific JSTL features and advantages
This section briefly summarizes some advantages of using three of the four available JSTL custom tag libraries and some reasons not to use the JSTL database access library. I also discuss the advantages of using EL in this section.
Database access library
JSTL provides a database access custom tag library, but I seldom use it because I strongly feel that you should not implement database access directly inside JSPs. Accessing a database directly from a JSP reduces reuse because the database access code is not accessible outside the specific JSP in which the database tags are used. Direct database access in JSPs indicates strong coupling between the presentation and database tiers. Disciplined separation means more modularity, greater opportunity for reuse, and better opportunities for specialization of presentation and database experts. While I recommend using the other three JSTL tag libraries when they satisfy a JSP developer's needs, I do not recommend using the JSTL database access library outside of prototypes and the simplest Web applications.
JSTL core tag library
As its name suggests, the JSTL core tag library is the most commonly used of the four libraries. This tag library provides custom tags for iterating over collections, handling conditionals (if-else type constructs), and other familiar procedural constructs. This tag library alone saves JSP developers from writing many of their own custom tags or embedding Java directly in JSPs.
JSTL XML tag library
This tag library supplies developers with a surprisingly versatile collection of XML manipulation tags and XSLT transformation tags.
JSTL formatting tag library
For Webpages and Websites available in multiple countries and/or languages, internationalization (I18N) can be one of the more challenging aspects of Web development projects. The JSTL formatting tag library helps JSP developers meet this challenge with custom tags that support writing and reading numbers and dates appropriately for the specified locale.
JSTL has two tag types for these custom tag libraries: traditional request time (RT) custom tags and EL tags. Because EL is more flexible, I recommend using the EL custom tag libraries rather than the RT libraries.
According to the JSP 2.0 Specification Proposed Final Draft 2, all JSP tags will support an EL. Getting to know EL now by using JSTL's EL custom tag versions will make this transition smoother.
JSTL and other custom tag libraries
Because custom tags have been supported for much longer than JSTL has been available, many individuals and organizations have developed custom tag libraries that largely overlap with JSTL. In most cases, I recommend first using JSTL when possible instead of homegrown custom tag libraries or other publicly available custom tag libraries that implement the same functionality. The standardization provided by JSTL is a significant advantage because the tag APIs can be learned once and used consistently.
Comparing Struts tag libraries and JSTL provides a good example of how to implement this best practice. Struts provides many advantages beyond the Model-View-Controller (MVC) framework with which it is commonly associated. One additional advantage is its set of custom tag libraries. Struts custom tags supported iterations and conditionals long before JSTL was available. However, I am now beginning to use JSTL iteration and conditional tags rather than the Struts equivalents. I still use Struts form tags because they are closely tied with Struts form handling, and no JSTL equivalent exists.