Include|js| News
This article is a follow-up article from the Java Brett McLaughlin following the first JSP best practices article, and in this article, the author shows you how to extend the inclusion functionality for dynamic content in JSP technology. Understand the differences between static include pseudo directives and dynamic jsp:include elements, figuring out how to mix and match them to get the best performance.
In the previous article in the new JSP best Practices series, you learned how to use JSP include pseudo directives to include static content such as headers, footers, and navigation components in a Web page. As with server-side inclusion, JSP include pseudo directives allow a page to extract content or data from another page. Listing 1 revisits the include pseudo directives.
Listing 1. JSP include pseudo instruction
<! [cdata[
<%@ page language= "java" contenttype= "text/html"%>
<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"/>
<body>
<%@ include file= "header.jsp"%>
<%@ include file= "navigation.jsp"%>
<%@ include file= "bookshelf.jsp"%>
<%@ include file= "/mt-blogs/index.jsp"%>
<%@ include file= "footer.jsp"%>
</body>
]]>
What you need
All of the best practices in this series are based on the JavaServer Pages technology. To run any of these best practices, you need to install a WEB container that conforms to JSP technology on your local machine or test server. You will also need to encode the JSP pages using a text editor or IDE.
Although include is ideal for incorporating static content into Web pages, it is not as satisfying as dynamic content. We found this problem in our previous article when we tried to reload the cache file. Unlike most header files and footer files, dynamic content changes frequently and must be updated at all times. We'll begin by briefly restating the limitations of the include pseudo directives, and then I'll show you how to extend the capabilities of the JSP with jsp:include tags.
Cache problem
One of the drawbacks of JSP include pseudo directives is that it causes the Web browser to cache all pages at cache. This is useful when working with static components such as footers, copyright notices, or a set of static links. These files do not change, so there is no reason for the JSP interpreter to repeatedly poll the data. Cache should be implemented wherever possible, as it improves the performance of the application.
JSP Testing and development
When you build a Web application or Web site, you may need to update headers, footers, and navigation links in large numbers. It can be painful to be forced to shut down the browser or clear its cache just to see the changes that are made to the included files. On the other hand, it is painful to end the development cycle and have to thoroughly review and modify hundreds of pages that use the include pseudo directives. My advice is to disable the browser cache during testing. In most cases, this can completely solve the problem. There are also rare cases where this does not work, and you can constantly restart the Web container on the browser or server to ensure that caching is not done.
Sometimes, however, caching is not worth the candle. If you are using a program that uses dynamic data, such as Weblog or database-driven JSP files, or even if the content is a frequently changing HTML (such as a timestamp), you will need to display the latest version of those files or programs whenever you load a Web page. Unfortunately, JSP include pseudo directives do not have this functionality. In the Test and development cycle (see Sidebar, "JSP Test and development"), disabling caching in a browser can often solve the problem. However, for applications that are actually used, performance is an important factor in any design decision process, and disabling caching is not a viable long-term measure. A better solution is to use the jsp:include tag.
Jsp:include Mark
Jsp:include is nothing more than a pseudo instruction that is different from include. The advantage of jsp:include is that it always checks for changes in the contained files. In a moment we will look at how this new marker works. But first take a look at the two kinds of code, so that you can see the similarities and differences.
Listing 2 shows a simple page that uses the original JSP include pseudo directives.
Listing 2. JSP include pseudo instruction
<! [cdata[
<%@ page language= "java" contenttype= "text/html"%>
<title>jsp include element test</title>
<body>
This content is statically in the main JSP file.<br/>
<%@ include file= "included.html"%>
</body>
]]>
Listing 3 is the same page, except that it's turned into using the jsp:include tag.
Listing 3. Turn to use Jsp:include
<! [cdata[
<%@ page language= "java" contenttype= "text/html"%>
<title>jsp include element test</title>
<body>
This content is statically in the main JSP file.<br/>
<jsp:include page= "included.html" flush= "true"/>
</body>
]]>
You should be aware of the two major differences between the two types of code. First, the Jsp:include element does not use the%@ syntax that belongs to the include pseudo directive. In fact, the JSP prefix lets the JSP compiler know that it should look for elements in a standard JSP tag set. Second, you specify the properties of the file you want to include from file into page. If you want, you can test the results of the new tag yourself. Just change the contents of the included.html file in the previous article (see Resources) and reload the browser page to see the new content immediately.
Flush Property
You may have noticed the flush property in the Jsp:include code example. As the name suggests, flush indicates whether to empty any existing buffers before reading the containing content. The flush attribute is required in JSP 1.1, so if you do not use it in your code, you will get an error. However, in JSP 1.2, the Flush property defaults to False. Since emptying most of the time is not an important issue, my advice is to set flush to true for JSP 1.1, and to turn it off for JSP 1.2 and later.
How Jsp:include is working.
If you're a bit inquisitive, you might be wondering why the jsp:include tag behaves differently from the include pseudo directive. The truth is very simple: Jsp:include contains the response of the included URI, not the URI itself. This means that the indicated URI is interpreted so that it contains the generated response. If the page is HTML, you'll get HTML that doesn't change at all. However, if it is a Perl script, a Java servlet, or a CGI program, you will get the result that is interpreted from the program. Although the page is usually HTML, the actual program is just the way to achieve it. Also, because it is interpreted every time the page is requested, the results are never cached as if the include pseudo directives were used. Although this is a small change, it causes all the differences in the behavior you see.
A mix-and-match solution
Include pseudo directives are useful on some sites. For example, if a site contains some headers, footers, and navigation files that have little or no change, the basic include pseudo directives are the best options for these components. Because the include pseudo directives are cached, the content is cached only once, and the result is a significant increase in the performance of the site.
However, a carpet cache does not solve the problem for many WEB applications or sites today. Although headers and footers may be static, it is not possible for the entire site to be static. For example, it is common to extract navigation links from a database, and many JSP technology-based sites also extract content from dynamic JSP pages on other sites or applications. If you are working with dynamic content, you need to use Jsp:include to process the content.
The best solution, of course, is to mix the two methods often, using each construct in the most appropriate place. Listing 4 is an example of a mix-and-match containing solution.
Listing 4. Mix and Match Solutions
<! [cdata[
<%@ page language= "java" contenttype= "text/html"%>
<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"/>
<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>
]]>
The code above shows the sample index page in the previous article. Navigation links and footers are static content that is changed at most once a year. For these files, I use the include pseudo directives. The content pane contains Weblog and "bookshelf" components, which are dynamically generated. These two components need to be updated all the time, so for them, I use the jsp:include tag. header.jsp file is a bit strange. This component is extracted from another, essentially static, JSP page. However, as you will notice, it extracts the page "banner" from the containing page and then displays it. To handle this shared information, we must pass parameters to the header file. To handle those parameters, you must use the Jsp:include element.