|
|
|
Contents: |
|
|
|
Related content: |
|
|
|
Subscriptions: |
|
|
| A simple JSP tag for building dynamic Web sites
Brett
McLaughlin (mailto:brett@oreilly.com?cc=&subject=Manipulate
dynamic content with jsp:include) Author, O'Reilly and
Associates 29 April 2003
In this follow-on to his first JSP best
practices installment, Java tipster Brett McLaughlin shows you how
to extend the JSP technology inclusion functionality for dynamic
content. Learn the differences between the static include
directive and the dynamic jsp:include element, and find out
how to mix and match the two for optimum
performance.
In the previous installment in the new JSP best practices
series, you learned how to use the JSP include directive to
include static content such as header, footer, and navigation components
into your Web pages. Like server-side includes, the JSP
include directive lets one page pull in content or data from
another page. Listing 1 will refresh your memory of the
include directive. Listing 1. The JSP
include directive
<![CDATA[
<%@ page language="java" contentType="text/html" %>
<html>
<head>
<title>newInstance.com</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1" />
<link href="/styles/default.css"
rel="stylesheet" type="text/css" />
</head>
<body>
<%@ include file="header.jsp" %>
<%@ include file="navigation.jsp" %>
<%@ include file="bookshelf.jsp" %>
<%@ include file="/mt-blogs/index.jsp" %>
<%@ include file="footer.jsp" %>
</body>
</html>
]]>
|
What you'll need All of the best
practices in this series are based on JavaServer Pages technology.
To run any of them, you'll need to set up a JSP technology-compliant
Web container, either on your local machine or on a test server.
You'll also need to use a text editor or IDE to code your JSP
pages. |
While include works very well for incorporating static
content into your Web pages, it doesn't work so well for dynamic content.
We discovered this in the last installment when we attempted to reload a
cached file. Unlike most header and footer files, dynamic content changes
frequently and must always be up to date. We'll start out with a quick
recap of the limitations of the include directive, then I'll
show you how to extend the JSP inclusion capability with the
jsp:include tag.
The trouble with
caching One of the downsides of the JSP include
directive is that it causes your Web browser to cache complete pages. This
makes sense when it comes to dealing with static components such as a
footer, a copyright notice, or a set of static links. These files don't
change, so there's no reason for the JSP interpreter to constantly re-poll
their data. And caching should be implemented wherever possible, because
it aids your application performance.
JSP testing and development When
you're building a Web application or Web site, you may need to
update your headers, footers, and navigation links quite a bit. It
can be a pain to have to constantly close out your browser or clear
its cache just to see the changes you've made to your included
files. On the other hand, it's just as much of a pain to come to the
end of your development cycle only to have to sweep through and
change hundreds of pages that employ the include
directive. My advice is to disable your browser cache during
testing. In most cases this will resolve the problem altogether. In
the rare cases where this doesn't work, you can always restart your
Web container to ensure no caching is occurring, either on the
browser or on the server. |
In some cases, however, caching can cause more trouble than it's worth.
If you're pulling in content from a program that uses dynamic data (such
as a Weblog or a database-driven JSP file), or even if your included
content is a highly volatile bit of HTML (such as a time stamp), then you
need the latest version of these files or programs to show up whenever
your Web page is loaded. And unfortunately the JSP include
directive doesn't have that functionality. This problem is commonly
handled in the test-and-development cycle (see the sidebar "JSP
testing and development") by disabling caching on the browser. But for
working applications, where performance is an important factor in any
design decision, disabling caching isn't a viable long-term solution. A
better solution is to use a jsp:include tag.
The jsp:include
tag
jsp:include is simply a different directive
from include . The advantage of jsp:include is
that it will always check for changes in the included file. We'll
get into how the new tag works in just a moment. But first we'll take a
look at the code for each of the two include s, so that you
can see the similarities and differences between them.
Listing 2 shows a simple page that uses the original JSP
include directive. Listing 2. The JSP
include directive
<![CDATA[
<%@ page language="java" contentType="text/html" %>
<html>
<head>
<title>JSP include element test</title>
</head>
<body>
This content is statically in the main JSP file.<br />
<%@ include file="included.html" %>
</body>
</html>
]]>
|
Listing 3 is the same page converted to use the
jsp:include tag. Listing 3. Converting
to jsp:include
<![CDATA[
<%@ page language="java" contentType="text/html" %>
<html>
<head>
<title>JSP include element test</title>
</head>
<body>
This content is statically in the main JSP file.<br />
<jsp:include page="included.html" flush="true" />
</body>
</html>
]]>
|
You should notice two big differences between the two code types.
First, the jsp:include element doesn't use the
%@ syntax that is part of the include directive.
Instead, the jsp prefix lets the JSP compiler know that it
should look for the element in the standard JSP set of tags. Second, the
attribute that specifies the file to include has changed from
file to page . If you like, you can test the
results of the new tag for yourself. Simply change the content of your own
included.html file from the last installment (see Resources),
reload your browser page, and you'll see the new content immediately.
The flush attribute You may have
noted the flush attribute in the
jsp:include code example. As its name suggests,
flush indicates whether any existing buffer should be
flushed before reading in the included content. The
flush attribute is required in JSP 1.1, so you'll get
an error if you leave it out of your code. In JSP 1.2, however, the
flush attribute defaults to false. Because flushing is
rarely a big concern, my advice is to leave flush set
to true for JSP 1.1 and leave it off for JSP 1.2 and
above. |
How jsp:include
works If you're even mildly geeky, you're probably anxiously
wondering why the jsp:include tag behaves differently from
the include directive. It's actually pretty simple:
jsp:include includes the response from the included
URI, rather than the URI itself. This means that the indicated URI is
interpreted and the resulting response is included. If the
page is HTML, you get the HTML essentially unchanged. But if it's a Perl
script, a Java servlet, or a CGI program, you'll get the interpreted
result from that program. While this usually turns out to be HTML, the
actual program is just a means to an end. And, because interpretation
happens at every page request, the results are never cached as they were
with the include directive. It's such a minor change, but it
makes all the difference in the behavior you see.
A mix-and-match
solution The include directive has its place on
some Web sites. For example, if your site includes header, footer, and
navigation files that rarely (if ever) change, then the basic
include directive is a fine choice for these components.
Because the include directive mandates caching, you'll only
need to pull in the included files once, the content will be cached, and
your site will receive a nice performance boost as a result.
For many of today's Web applications or sites, however, blanket caching
won't work. While your headers and footers may be static, it's unlikely
that your whole site will be. It's not uncommon to pull navigation links
from a database, for example, and many JSP technology-based sites pull
content from dynamic JSP pages on other sites or applications. If you are
dealing with dynamic content, you will need to employ
jsp:include s to handle that content.
Of course, the best solution is often to mix and match, using each
construct where it is most appropriate. Listing 4 is an example of a
mix-and-match include solution. Listing 4. A
mix-and-match solution
<![CDATA[
<%@ page language="java" contentType="text/html" %>
<html>
<head>
<title>newInstance.com</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href="/styles/default.css" rel="stylesheet" type="text/css" />
</head>
<body>
<jsp:include page="header.jsp" flush="true">
<jsp:param name="pageTitle" value="newInstance.com"/>
<jsp:param name="pageSlogan" value=" " />
</jsp:include>
<%@ include file="/navigation.jsp" %>
<jsp:include page="bookshelf.jsp" flush="true" />
<jsp:include page="/mt-blogs/index.jsp" flush="true" />
<%@ include file="/footer.jsp" %>
</body>
</html>
]]>
|
The above code shows the example index page from the previous
installment. The navigation links and footer are static content, changing
once a year at most. For these files, I've used the include
directive. The content pane includes Weblog and "bookshelf" components,
which are generated dynamically. Both of these components need to be
always up to date, so for them I've used the jsp:include tag.
The header.jsp file is the oddball of the lot. This component
is pulled from another JSP page that is essentially static. But, as you'll
note, it pulls in the page "slogan" from the including page and writes
that out. To deal with this shared information, I have to pass in
parameters to the header file. And to deal with those parameters, I have
to use the jsp:include element.
If you're wondering about those parameters, rest assured that you won't
wonder for long. In the next installment, I'll explain JSP parameters and
how they interact with JavaBeans components. Until then, I'll see you
online.
Resources
- To do the exercises in this series, you'll need a JSP-compatible Web
container, like Apache
Tomcat.
- You may also want to look into using a JSP-compliant IDE. Here are
several to choose from:
- Learn more about the
include directive, in the first
installment in this series. See the entire
JSP best practices series.
- We only briefly discussed the use of JSP in development and testing
here, but the topic is greatly expanded in the article "Test
and document Java code rapidly with JSP Explorer"
(developerWorks, August 2001).
- For a guided introduction to JSP technology, try Noel Bergman's
tutorial "Introduction
to JavaServer Pages technology" (developerWorks, August
2001).
- For the nitty-gritty details of JSP technology, your best bet is to
read the JSP
specification.
- Hans Bergsten's JavaServer
Pages (O'Reilly & Associates, 2002) is an indispensable
resource for learning about JSP.
- "Ten
JSP technology books compared" is a little bit outdated
(developerWorks, June 2001), but it's still a fine review of
worthwhile JSP titles.
- If you like JSP best practices, you might also want to check
out the EJB
best practices series.
- JSP technology is based on Java Servlets technology. Learn more
about Servlets by reading Jason Hunter's Java Servlet
Programming (O'Reilly & Associates, 2002).
- See the developerWorks
Java technology tutorials page for a complete listing of free Java
technology tutorials from developerWorks.
- You'll find hundreds of articles about every aspect of Java
programming (including more articles on JSP technology) in the developerWorks
Java technology zone.
About the
author Brett McLaughlin has been working in computers
since the Logo days (remember the little triangle?). He currently
specializes in building application infrastructure using Java and
Java-related technologies. He has spent the last several years
implementing these infrastructures at Nextel Communications and
Allegiance Telecom Inc. Brett is one of the co-founders of the Java
Apache project Turbine, which builds a reusable component
architecture for Web application development using Java servlets. He
is also a contributor of the EJBoss project, an open source EJB
application server, and Cocoon, an open source XML Web-publishing
engine. Contact Brett at brett@oreilly.com. |
|
|