[ Team LiB ] Previous Section Next Section

Including Other Files

Using tags to perform functions can make your JSPs more readable, since they are used in a manner that is similar to other tags on the page. As you'll see in later hours, they significantly reduce the number of transitions between Java code and other elements of the JSP. In many cases, they can replace all of the scriptlets and expressions you might have used to construct a page. In addition, some of the standard tags can help you structure your applications to make them even easier to work with.

Splitting your code is one of the first techniques you can use to organize your code. Many sites have a consistent header on every page. You can put the header into a separate file and include it in every page. When you need to change the header, you need to change only one file.

Within a JavaServer Page, you can choose to include another file at page compile time or at runtime. The advantage of including a file at compilation time is performance. At runtime, the JSP engine doesn't need to do any work because the file has already been included. Unfortunately, with servlets, you can only include files at runtime. After all, you are the one who compiles the servlet. How could the container include something at runtime?

To include another file at compile time, use the include directive, like this:


<%@ include file="includedFileName" flush="true"%>

The Path to an Included File Is Relative

graphics/bytheway_icon.gif

The path for the included file is relative to the path of the original JSP. That is, if the included file is in the same directory as the including file, you don't need to specify a directory name.


Listing 10.1 shows a JSP file that includes another file. Because the file is included at compile time, you can look at the generated servlet and see that the included code is there.

Listing 10.1 Source Code for CrazyWorld.jsp
<html>
<body>
<%@ include file="Header.html" %>
<p>
Welcome to <i>It's a Crazy World</i>
<p>
</body>
</html>

By putting all your header code in a single file, you can make sure that all your pages have an identical header. When you change the header, you need to change only one file.

Listing 10.2 shows the Header.html file included by CrazyWorld.jsp.

Listing 10.2 Source Code for Header.html
<table bgcolor="#0000ff">
<tr><td><img src="face.jpg" align=left></td>
<td><h1><font color="#ffff00">It's a Crazy World</font></h1></td>
<td><img src="face.jpg" align="right"></td></tr>
</table>

Figure 10.1 shows CrazyWorld.jsp as it appears in a browser. The image and header come from Header.html, whereas the welcome message comes from CrazyWorld.jsp itself.

Figure 10.1. You can include header information at compile time by using <%@ include %>.

graphics/10fig01.gif

When you include a file with the include directive, the JSP compiler processes the included file as if it were part of the JSP. You can use any JSP directives within the included file and can even include another file. Any variables and methods defined in the main JSP are available to included files.

Has It Changed? Your Container Might Not Know.

graphics/watchout_icon.gif

The JSP specification does not provide a standard way for a JSP engine to learn that an included file has changed. Tomcat can detect whether an included file is changed. If you are using another engine, you should determine if that engine does also.


Although there is a potential speed gain in including files at compile time, you give up a lot of flexibility. When you include files at runtime, you are able to freely mix servlets and JavaServer Pages.

Having Trouble with the Example?

graphics/bytheway_icon.gif

If you are having trouble including a file at compile time, see the "Q&A" section at the end of this hour.


Including Files in a JSP at Runtime

When you want to include a servlet or another JSP into your JSP, use the <jsp:include> directive, like this:


<jsp:include page="includedFileName" flush="true"/>

The flush attribute indicates whether the output buffer should be flushed before the file is included. The default value for this attribute is false.

Listing 10.3 shows a menu JavaServer Page that displays a tab-style menu, highlighting a specific menu item according to a parameter that is passed to it.

Listing 10.3 Source Code for Menu.jspf
<%
// See which menu item should be highlighted.
    String highlighted = request.getParameter("highlighted");

// Set the names for the individual menu items.

    String welcome = "welcome.jpg";
    if (highlighted.equalsIgnoreCase("welcome"))
        welcome = "welcomeS.jpg";

    String products = "products.jpg";
    if (highlighted.equalsIgnoreCase("products"))
        products = "productsS.jpg";

    String services = "services.jpg";
    if (highlighted.equalsIgnoreCase("services"))
        services = "servicesS.jpg";

    String support = "support.jpg";
    if (highlighted.equalsIgnoreCase("support"))
        support = "supportS.jpg";

    String aboutUs = "aboutUs.jpg";
    if (highlighted.equalsIgnoreCase("aboutUs"))
        aboutUs = "aboutUsS.jpg";
%>
<table cellpadding="0" cellspacing="0">
<tr>
<td><a href="welcome.jsp"><img src="<%=welcome%>" border="0"></a></td>
<td><a href="products.jsp"><img src="<%=products%>" border="0"></a></td>
<td><a href="services.jsp"><img src="<%=services%>" border="0"></a></td>
<td><a href="support.jsp"><img src="<%=support%>" border="0"></a></td>
<td><a href="aboutUs.jsp"><img src="<%=aboutUs%>" border="0"></a></td></tr>
</table>

Because Listing 10.3 is intended to be used within other JSPs, it's given a different extension—jspf, which originally stood for JSP fragment. Although the specification does not require you to use this extension, it does recommend its use. In spite of the extension origin, the specification calls these types of files JSP segments to avoid confusion between them and a new type of fragment that you'll learn about in Hour 16, "Extending JSP with New Tags."

Listing 10.4 shows a JSP that uses the <jsp:include> tag to include the Menu.jsp.

Listing 10.4 Source Code for support.jsp
<html>
<body bgcolor="#ffffff">
<%@ include file="Header2.html"%>

<jsp:include page="Menu.jspf" flush="true">
    <jsp:param name="highlighted" value="support"/>
</jsp:include>
<p>
<h1>Frequently Asked Questions</h1>
<p>
<i>What in the world is a Zither?</i>
<br>
A zither is a stringed instrument that has between 30 and 40 strings.
<p>
<i>How do you expect to earn money if all you sell is zithers?</i>
<br>
We don't. This business is a tax write-off for our highly successful
Amalgamated Golf Tees, Inc.

</body>
</html>

Some Notes About Some "Advanced Features" of Listing 10.4

graphics/bytheway_icon.gif

Listing 10.4 uses the <jsp:param> tag (discussed later in this hour) to tell the Menu.jsp file which item to highlight. It also uses an include directive to include a standard header.


Figure 10.2 shows the output of support.jsp. The menu items are generated by the Menu.jsp file.

Figure 10.2. You can use the <jsp:include> tag to implement a menu.

graphics/10fig02.gif

There are a few restrictions imposed on files when they are included at runtime. These restrictions are not imposed on files that are included at compile time. An included file cannot change any header information sent back to the browser. For example, you cannot set any cookie information from within an included file.

Having Trouble with the Example?

graphics/bytheway_icon.gif

If you are having trouble including a file at runtime, see the "Q&A" section at the end of this hour.


Passing Parameters to an Included File

Included files can access all the information in the request object, so they have access to any form variables passed from the browser. In addition, you can pass parameters to the included file by using the <jsp:param> directive:


<jsp:include page="someIncludedPage" flush="true">
    <jsp:param name="myParamName" value="paramData"/>
</jsp:include>

Directives and End Tags

graphics/bytheway_icon.gif

The <jsp:include> tag follows the XML standard of ending a tag with /> when there is no closing tag. When you include a file and don't pass any parameters, end the <jsp:include> tag with />. When you pass parameters with <jsp:param>, you include a closing </jsp:include> tag. Notice, too, that the <jsp:param> tag closes with a />.


The included file uses request.getParameter and request.getParameterValues to fetch the parameters just as if the parameters were passed from the browser as form variables. Values from <jsp:param> take precedence over parameters already in the request. In other words, if you use getParameter to retrieve the parameter value, you get the value specified in <jsp:param>. If you use getParameterValues, you get both the value specified by <jsp:param> and the value passed from the browser.

Visibility of Parameters

graphics/bytheway_icon.gif

The parameters added with the <jsp:param> tag are visible to the included page only. They are not visible to the original page (that is, they don't affect the original set of parameters).


Listing 10.5 shows a page that passes a parameter to an included page.

Listing 10.5 Source Code for MainForm.jsp
<html>
<body bgcolor="#ffffff">
<jsp:include page="IncludedForm.jspf" flush="true">
    <jsp:param name="myVar" value="I was passed from main"/>
</jsp:include>
</body>
</html>

Listing 10.6 shows the included page that uses getParameter and getParameterValues to print out the values for myVar.

Listing 10.6 Source Code for IncludedForm.jspf
<pre>
<%
    String myVar = request.getParameter("myVar");
    String myVars[] = request.getParameterValues("myVar");

    out.println("myVar = "+ myVar);
    out.println("The values for myVar are:");
    for (int i=0; i < myVars.length; i++)
    {
        out.println(myVars[i]);
    }
%>
</pre>

Notice that the included form doesn't contain <html> or <body> tags. The form always assumes that it has been included from another page and that the surrounding page contains those tags. Figure 10.3 shows the output from MainForm.jsp. The original value for MainForm.jsp is passed as part of the URL, as you can see in the address line on the browser.

Figure 10.3. Included pages usually assume that they are included and don't contain <html> or <body> tags.

graphics/10fig03.gif

Including Files from a Servlet

The servlet API has a peculiar way to include files. Although you might expect either the request or response objects to provide a method to include a file, it's not that simple. To include another servlet, JSP, or text file, you must obtain a request dispatcher for the resource you want to include.

Fortunately, you can obtain a request dispatcher quite easily. The fastest way to get a request dispatcher is to call request.getRequestDispatcher and pass it through the URL of the resource you want to include, like this:


RequestDispatcher d =
        request.getRequestDispatcher("destinationURL"");
d.include(request, response);

Listing 10.7 shows a servlet that includes the IncludedForm.jsp from Listing 10.6.

Listing 10.7 Source Code for MainFormServlet.java
package examples;

import javax.servlet.*;
import java.io.*;

public class MainFormServlet extends GenericServlet
{
    public void service(ServletRequest request,
        ServletResponse response)
        throws IOException, ServletException
    {
// Tell the web server that the response is HTML.
        response.setContentType("text/html");

// Get the PrintWriter for writing out the response.
        PrintWriter out = response.getWriter();

// Write the HTML back to the browser.
        out.println("<html>");
        out.println("<body>");

// Get the request dispatcher for the JSP to include.
        RequestDispatcher dispatcher =
            request.getRequestDispatcher(
                "/IncludedForm.jspf");

        dispatcher.include(request, response);

        out.println("</body>");
        out.println("</html>");
    }
}

GenericServlet or HttpServlet?

graphics/bytheway_icon.gif

Developers will often extend HttpServlet in most servlets they write. In this example, it extends GenericServlet because it only requires the service method. You can use either HttpServlet or GenericServlet.


The output from the included resource is written to the stream of the response object passed to it through the include method.

Listing 10.7 uses the full pathname for the included JSP. The servlet is not in the same directory as the JSP it is including. The getRequestDispatcher method takes a relative URL, so if you include another servlet that is in the same directory as your servlet, you don't have to specify the full pathname.

Don't Forget the Parameters

graphics/watchout_icon.gif

If you run this example, don't forget to provide parameters to the servlet. The URL for this example will look something like this:

http://localhost:8080/servlet/examples.MainFormServlet?myVar=aVar

In the last example, the JSP provided the parameters within the main JSP.


Passing Parameters to an Included Resource

graphics/didyouknow_icon.gif

To pass parameters to a resource you are including, add the parameters to the URL when you call getRequestDispatcher—for example, getRequestDispatcher ("MyForm.jsp?param1=avalue").


    [ Team LiB ] Previous Section Next Section