Further JSP Syntax
In the previous chapter, you were exposed to the core of the JSP syntax. The chapter showed you how to embed Java code into your pages, it showed you the predefined variables, and it introduced you to the JavaServer Pages Standard Tag Library (JSTL).
In this chapter, see the role of what are known as standard actions, and you will be introduced to custom actions. The chapter will then progress to the Expression Language where you will discover how it can be used directly within pages, reducing further the need to have Java code embedded in your pages.
The Standard Actions
Since the earliest versions of JSP, there have been what are referred to as standard actions. These are special XML-like tags (XML is discussed in the introduction to Chapter 10, "Utilizing XML from JSP"). They take the form of an XML tag with a namespace-prefixed jsp, so a standard action always looks something like this:
<jsp:standardActionName . . . >. . .</jsp:standardActionName>
They are used for the following functions:
Forwarding requests and performing includes in pages.
Embedding the appropriate HTML on pages to invoke the Java plugin to be used within browsers to run Java applets.
The interaction between pages and JavaBeans.
The provision of additional functionality to tag libraries.
We'll look at these functions here, and you will see some being used in other contexts in later chapters.
Forwarding and Including
When a request is received by a JSP, it can be forwarded directly onto another relative URL from the same Web application to be processed. This must be a resource within the same Web application. To do this, you can use the <jsp:forward> standard action.
Forwarding is not the same as redirecting. Redirecting involves the browser being sent elsewhere for a resource, effectively resulting in the browser issuing two requests. Forwarding is the browser requesting a resource, and the response coming from the resource that has been forwarded to. Following is a basic page, which uses the <jsp:forward> standard action:
anything here will not appear in the browser <jsp:forward page="gotForwardedRequest.jsp"/> anything here will not appear either
Pages that forward requests cannot send any content to the browser. In the very basic example shown previously, neither of the two fragments of text will appear in the browser because the request and response have been forwarded to gotForwardedRequest.jsp.
Use of the <jsp:forward> action creates the automatically generated code in the compiled servlet, as shown in Listing 3.1.
Listing 3.1 Autogenerated Source from JSP Using <jsp:forward>
// note that some code has been removed for brevity public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { ... try { . . . out.write("anything here will not appear in the browser\r\n"); if (true) { pageContext.forward("gotForwardedRequest.jsp"); return; } out.write("\r\nanything here will not appear either"); } catch (Throwable t) { if (out != null && out.getBufferSize() != 0) out.clearBuffer(); if (pageContext != null) pageContext.handlePageException(t); ... } }
You can see from Listing 3.1 that the standard action becomes a call to the forward() method of the javax.servlet.jsp.PageContext object.
In the example, the textual output in the forwarding page never gets written to the browser, as immediately following the forward() call, the service method returns. This is because the output is all in the buffer, and this is never flushed as the request is forwarded.
If the forwarding page has already committed output to the browser by flushing the buffer, then the forwarding will fail. The following modification will not allow the forwarding to happen:
anything here will now appear in the browser <% out.flush(); %> <jsp:forward page="gotForwardedRequest.jsp"/> anything here will not appear as the output is flushed
This listing will display the first line of text and nothing else when viewed in a browser. No forwarding will take place. This is because of the presence of the out.flush() method call. This method will flush the JspWriter buffer, and after content is committed to the browser, a forward cannot be invoked. If it is tried, an IllegalStateException is thrown, and this is caught by the catch block that you can see in Listing 3.1.
The chapter download includes two JSPs, getRequest.jsp and gotForwardedRequest.jsp, which you can use to try this out.
So, you have seen how the <jsp:forward> standard action works, but why would you use it? Because it can only be used on pages that are not outputting anything to the browser, it is only really useful on pages that aren't being used to display any contentcontroller pages if you like. The concept of a controller is discussed in Chapter 7, "JSP Application Architecture."
Passing Parameters
It is also possible to pass parameters from one page to another when carrying out forward actions. To do this, another standard action is usedthe <jsp:param> action. Take a look at the following listing, which passes these parameters:
<jsp:forward page="accessingParameters.jsp"> <jsp:param name="myParam" value="John Doe"/> </jsp:forward>
Here is the relevant fragment of the resultant servlet code:
. . . if (true) { pageContext.forward ("accessingParameters.jsp" + "?" + "myParam=" + "John+Doe"); return; } . . .
You might be able to identify what this param action has done. It has appended the parameter as a variable within the query string.
This is now accessible to the resource that the request was forwarded to using a basic statement like:
String value = request.getParameter("myParam");
This ability to pass parameters can be very helpful because the values of these parameters can be dynamic.
A complete example of this is part of the chapter download as pages passingParameters.jsp and accessingParameters.jsp.
Templating Pages Using <jsp:include>
The third standard action we will discuss is the <jsp:include> action. In Chapter 2, the include directive was introduced, which includes static content into your JSP.
The include directive is not always appropriate, however, because the included content is included as static text (see Chapter 2). The include standard action, however, processes any included files at runtime. In other words, when the servlet is invoked by a client, the included file is dynamically obtained. This results in the ability to include content that is being changed regularly, and also the ability to include output from other JSPs that are providing dynamic content.
The include action can be used to include the output from one JSP within another, and thus, you can build up templates of JavaServer Pages that make up complete Web pages. In fact, this is how the front ends of many Web sites are built. Figure 3.1 shows a diagram of what is meant by this.
Figure 3.1 Templating using <jsp:include>.
Listing 3.2 shows a JSP that is built in this way with the use of includes.
Listing 3.2 usingIncludes.jsp
<html> <head> <title>Using Includes</title> </head> <body> <!-- header page inserted here --> <jsp:include page="tableheader.html" flush="true"/> <!-- main content inserted here--> <jsp:include page="maincontent.jsp" flush="true"/> <!-- insert the footer here --> <jsp:include page="tablefooter.html" flush="true"/> </body> </html>
As you can see from Listing 3.2, the <jsp:include> action has two attributes. The two attributes are shown in Table 3.1.
Table 3.1 The Attributes of <jsp:include>
Name |
Description |
page |
This attribute specifies the page to be included. It must contain a relative URL. |
flush |
The flush attribute specifies what should happen to any buffered content that appears within the including page up until the include. See the short listing below: content here could be buffered <jsp:include page="include.jsp" flush="true"/> What happens to the text content here could be buffered can be determined by the value of the flush attribute. If the text is buffered, and the flush attribute is true, it will be flushed before the include is processed. If the flush attribute is set to false, any buffered content will not be flushed. The significance of this is that the buffer needs to be flushed for output to be sent to the browser, so most of the time, you set to true. There were some specific situations in JSP 1.1 a value of false was required. Note that the default is false, so you will need to specify a value of true. |
As with the <jsp:forward> standard action, you can also pass parameters to included pages using the <jsp:param> standard action. A basic example is shown here:
<jsp:include page="accessingParameters.jsp" flush="true"> <jsp:param name="myParam" value="John Doe"/> </jsp:include>
This can be very useful when included content has features that are dependent on the including page. Consider Listing 3.3.
Listing 3.3 usingIncludesWithParameters.jsp
<html> <head> <title>This page passes parameters</title> </head> <body> <!-- header from include--> <jsp:include page="includeFileNeedingAParameter.jsp"> <jsp:param name="department" value="Electrical"/> </jsp:include> Welcome to our electrical department. This <p> area is packed with excellent deals on electrical items. </body> </html>
Listing 3.3 shows a basic JSP for a department within a store. Each department has a name, which is passed to the included file for display. Here is the content of the included file:
<!-- the included file --> <h1><%=request.getParameter("department") %> Department</h1>
TIP
A common mistake is to put HTML markup for the head and body, and so on, into an include file. This results in malformed HTML because these tags will be in the including page! Make sure that your include only includes the markup that is necessary.
There isn't much to see here because it is an included file. The parameter is passed as a parameter on the request object and is accessed using the getParameter() method as you saw with the forwarding example.
The output from this example is shown in Figure 3.2.
An alternative to using <jsp:include> is to use a new JSP2.0 feature that allows you to add headers and footers to groups of JSPs. There is a tag that can be used in web.xml to specify either a header or footer to be added to each page. Below is an example of this entry:
<jsp-property-group> <url-pattern>*.jsp</url-pattern> <include-prelude>/WEB-INF/includes/header.jspf</include-prelude> <include-coda>/WEB-INF/includes/footer.jspf</include-coda> </jsp-property-group>
Figure 3.2 Output from usingIncludesWithParameters.jsp.
The <jsp-property-group> defines a group of pages, and within it you can set includes for the top of the pages <include-prelude>, and includes for the foot of the pages <include-coda>. This is ideal when you are using the same headers or footers on every single page. The <url-pattern> element specifies which JSPs are to be included in the group, in this case, all of them with the .jsp extension.
The Java Plugin
In this section, you will be introduced to three more standard actions:
<jsp:plugin>
<jsp:params>
<jsp:fallback>
You will also see an additional use for the <jsp:param> element.
If you are planning to use Java applets within your application, you need to make sure that the client browsers support the applet you plan to use. One of the most frustrating aspects of applet development is the fact that you are reliant on the client browser virtual machine. Although Java is sometimes referred to as a "write once, run anywhere" language, in my experience, writing Java applets can be more like "write once, debug everywhere!" This is because the virtual machines in the browsers have various issues depending on the browser in use, and the platform on which the browser is running. Microsoft stopped shipping a Java virtual machine with its browser, requiring it to be downloaded separately; and on XP platforms, even that is no longer permitted. So, the reality is this: The more widely used browser (Internet Explorer) does not have very straightforward support for Java applets, and none at all in certain environments.
The traditional way to embed a Java applet into an HTML page is shown in Listing 3.4. This listing will not work in Internet Explorer where a virtual machine is not installed.
Listing 3.4 applet.html
<html> <head> <title>Not using the Java Plugin</title> </head> <body> <h1>Applet running in the browser</h1> <applet code="BasicApplet.class" width="90%" height="100"> <param name="text" value="Hello from the applet"> </applet> </body> </html>
It is against this backdrop that the Java Plugin comes in. This neat little bit of software is a plugin to the browser; the same way that Shockwave or Real Audio can be installed as a plugin to your browser to provide support for complex animations or streamed media. The Java Plugin basically provides a Java virtual machine that can be used by browsers to run Java applets in a fully compliant virtual machine from Sun. Various plugins are available for various versions of the Java programming language.
The Java Plugin can be installed from http://java.sun.com/getjava/.
The fundamental problem with this is that going to this URL is fine for Java-savvy developers like you and me, but how many regular Internet users are going to want to "faff about" trying to find this URL simply so they can use your online calculator or whatever your applet does.
NOTE
Faffing is a British term often used to denote someone wasting time or not getting straight to the point.
The Java Plugin can be installed automatically if required, and this is achieved using some specific HTML that needs to go into your page. This is where the <jsp:plugin> include comes in really useful. Its role is to automatically put in the required HTML code to enable a browser to run your applet using the Java plugin, and also install it if it is not already present. Listing 3.5 demonstrates the use of the Java Plugin.
Listing 3.5 plugin.jsp
<html> <head> <title>Using the Java Plugin</title> </head> <body> <h1>Applet running in the plugin</h1> <jsp:plugin type="applet" code="BasicApplet.class" width="90%" height="100"> <jsp:params> <jsp:param name="text" value="Hello from the applet"/> </jsp:params> <jsp:fallback> Your browser can't display this applet. Sorry </jsp:fallback> </jsp:plugin> </body> </html>
NOTE
The sample application for this chapter has a basic applet that takes in a parameter and displays it. The code is available as part of the sample application, but is not shown because it is not relevant to the discussion.
The <jsp:plugin> standard action is the main action being used here. It specifies the applet class, and a number of other attributessome are shown and some are not. The complete list can be found in the JSP 2.0 specifications available from http://www.jcp.org/jsr/detail/152.jsp.
The <jsp:params> action is optional and is required if the applet is to be passed any parameters. These parameters are then set using the <jsp:param> action that you have seen before.
Finally, the <jsp:fallback> action specifies what is to be displayed in the browser if the browser does not understand the OBJECT or EMBED tags that have been embedded into the HTML as a result of the <jsp:plugin> markup. The resulting HTML that is created from the JSP shown in Listing 3.9 is shown in Listing 3.6. This can be viewed by selecting View/Source in the browser.
Listing 3.6 HTML Created by plugin.jsp
<html> <head> <title>Using the Java Plugin</title> </head> <body> <h1>Applet running in the plugin</h1> <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" width="90%" height="100" codebase="http://java.sun.com/products/ plugin/1.2.2/jinstall-1_2_2-win.cab#Version=1,2,2,0"> <PARAM name="java_code" value="BasicApplet.class"> <PARAM name="type" value="application/x-java-applet;"> <PARAM name="text" value="Hello from the applet"> <COMMENT> <EMBED type="application/x-java-applet;" width="90%" height="100" pluginspage="http://java.sun.com/products/plugin/" java_code="BasicApplet.class" name="text" value="Hello from the applet" > <NOEMBED> </COMMENT> Your browser can't display this applet. Sorry </NOEMBED></EMBED> </OBJECT> </body> </html>
The OBJECT tag is there for Microsoft Internet Explorer, and the EMBED tag is there for Netscape. When this page is running on a Windows platform, you will get a Java icon in your system tray. This is shown in Figure 3.3, which shows Internet Explorer showing this page.
Figure 3.3 plugin.jsp in the browser.
Using JavaBeans on Pages
Three standard actions are associated with the use of JavaBeans on JavaServer Pages. JavaBeans are Java classes written to a certain specification which includes that they can have get and set methods for their properties. They also have a public no argument constructor. The standard actions allow the instantiation of beans, and also the setting and getting of their properties:
<jsp:useBean> enables the use of JavaBeans within JavaServer Pages. It specifies the Beans to be used on a specific page.
<jsp:getProperty> is used to access Bean properties from pages.
<jsp:setProperty> is used to set properties from pages.
A basic example is shown here:
<!-- create an instance of the bean --> <jsp:useBean class="Book" id="book" scope="session"/> <!-- set the title property --> <jsp:setProperty name="book" property="title" value="Treasure Island"/> <!-- now display this property on the page --> <jsp:getProperty name="book" property="title"/>
The use of JavaBeans on pages is vital if you are going to even begin to separate your business logic from your presentation. These standard actions associated with JavaBeans were the first step in the JSP specifications to enable this to be done. The subject of JavaBeans and their use in JavaServer Pages is discussed in detail in Chapter 6, "JSP and JavaBeans."
Actions and Tag Libraries
It is now also possible to create your own custom actions in addition to the standard actions that have been discussed. Custom actions are discussed in Chapter 9, "Developing Custom Tag Libraries," because custom actions are basically custom tags.
When using actions, there are some additional helper standard actions that you have available to you. One such action is the <jsp:attribute> action.
Consider the following code fragment:
<jsp:include page="includeFileNeedingAParameter.jsp"/>
The <jsp:attribute> action enables you to replace any attributes in your tags with <jsp:attribute> tags, with the attribute value now being element content:
<jsp:include> <jsp:attribute name="page">includeFileNeedingAParameter.jsp</jsp:attribute> </jsp:include>
You might be wondering what the benefit of this would be. In this specific example there is no benefit, but, for example, when you have custom actions, you might want attribute values to contain XML-structured data. This would not be possible if you were using normal XML attributes because these cannot contain structured XML data. The attribute action also has an additional attribute called trim, which enables you to specify whether whitespace at the start and the end of the value is removed. The default value is true, which means it will trim the whitespace.
Another helper action is <jsp:body>. This element is used to explicitly specify the body content of a tag. The body content of a tag is the name given to the content between the opening and closing parts of a tag:
<jsp:someTag>here is the body content</jsp:someTag>
The body can be explicitly specified using <jsp:body> elements:
<jsp:someTag><jsp:body>here is the body content</jsp:body></jsp:someTag>
Clearly, this is somewhat superfluous, but when attributes have been specified using the <jsp:attribute> action, the body must be explicitly specified using this element because it is presumed the tag has no body content if it has <jsp:attribute> actions within it. An example of this is shown here:
<jsp:someTag> <jsp:attribute name="someAttribute">attribute value</jsp:attribute> <jsp:body>here is the body content</jsp:body> </jsp:someTag>
You have now seen the standard actions available to the JSP developer. The chapter will now move on to look at the JSP 2.0 expression language.