A JSP page consists of the following components:
- Directives
- Scripting Elements
- Declarations
- Expressions
- Scriptlets
- Actions
Table 21.1 lists some JSP tags and their meanings.
1. Directives
A JSP page may contain instructions to be used by the JSP container to indicate how this page is interpreted and executed. Those instructions are called directives. Directives do not generate any output directly, but tell the JSP engine how to handle the JSP page. They are enclosed within the <%@ and %> tags. The commonly used directives are page, include, and taglib.
1.1. page directive
The following is the syntax of the page directive:
<%@ page
[ language=”java” ]
[ extends=”package.class” ]
[ import=”{package.class | package.*}, …” ]
[ session=”true | false” ]
[ buffer=”none | 8kb | sizekb” ]
[ autoFlush=”true | false” ]
[ isThreadSafe=”true | false” ]
[ info=”text” ]
[ errorPage=”relativeURL” ]
[ contentType=”MIMEType [ ;charset=characterSet ]”|”text/html ;
charset=ISO-8859-1”]
[ isErrorPage=”true | false” ]
%>
The page directive has many attributes, which can be specified in any order. Multiple page directives may also be used, but in this case, except for the import attribute, no attribute should appear more than once. The code in boldface indicates the default values. Let us discuss the function of some attributes.
import
The value of this attribute is a list of fully qualified names of classes separated by commas (,), to be imported by the JSP file. To import all the classes of a package, use “.*” at the end of the package name. The following directive imports all the classes in the java.io and java.reflect packages and the class Vector that belongs to the java.utii package.
<%@ page import=”java.io.*, java.reflect.*, java.util.Vector” %>
The classes can then be referred from declarations, expressions, and scriptlets within the JSP document, without using the package prefix. You must import a class before using it. You can use import as many times as you wish in a JSP file. For example, the line of code we have just discussed can be written as three directives, as follows:
<%@ page import=”java.io.*n %>
<%@ page import=”java.reflect.*” %>
<%@ page import=”java.util.Vector” %>
Those directives are converted to the corresponding import statement in the generated servlet file. You need not import the classes of the packages java.lang, javax.servlet, javax.servlet. http, and javax.serviet.jsp, as they are imported implicitly.
session
This attribute indicates whether the JSP file requires an HTTP session. The following syntax is used:
session=”true | false”
If true is specified (this is the default value), the JSP file has a session object that refers to the current or new session. If the value is false, no session object is created. If your JSP file does not require a session, the value should be set to false for performance consideration.
buffer
Syntax:
buffer=”none | sizekb”
The buffer attribute indicates the size in kilobytes (default is 8kb) of the output buffer to be used by the JSP file. The value none indicates a buffer with zero size. In such a case, the output is written directly to the output stream of the response object of the servlet.
autoFlush
Syntax:
autoFlush=”true | false”
The autoFlush attribute specifies whether the buffer should be flushed automatically (true) when it is full. If set to false, a buffer overflow exception is thrown when the buffer becomes full. The default value is true. The value of autoFlush can never be set to false when the buffer is set to none.
isThreadSafe
Syntax:
isThreadSafe=”true | false”
This attribute indicates whether the JSP page can handle multiple threads simultaneously. If true (default value) is specified, the JSP container is allowed to send multiple concurrent client requests to this JSP page. In this case, we must ensure that the access to shared resources by multiple concurrent threads is effectively synchronized. If false is specified, the JSP container sends clients requests one by one using a single thread. This attribute basically provides information to the underlying servlet on whether it should implement the singleThreadModel interface or not. Tomcat generates the following servlet class declaration if false is specified.
public final class ThreadDemo_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
javax.servlet.SingleThreadModel {
In this case, the JSP container loads multiple instances of the servlet in the memory. It then distributes concurrent client requests evenly among these servlet instances for processing in a round- robin fashion.
If true is specified, the following code is generated:
public final class ThreadDemo_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
info
Syntax:
info=”text”
It allows us to specify a descriptive information about the JSP page. This information can be retrieved using the Servlet.getServletInfo() method.
contentType
Syntax:
contentType=”MIMEType [ ;charset=characterSet ]”
It specifies the MIME type and encoding used in the generated response to be sent to the client. MIME types and encoding supported by the JSP container can only be specified. The default MIME type and character encoding are text/html and iso-8859-1, respectively.
errorPage and isErrorPage
Syntax:
errorPage=”relativeURL”
isErrorPage=”true | false”
When an uncaught exception occurs in a JSP page, the JSP container sends information explaining the exception, which is undesirable for some cases such as commercial sites. The errorPage attribute specifies the relative path name of another JSP page to be displayed, in case an error occurs in the current page. In the error page, the isErrorPage attribute must be set to true. The error page can access the implicit exception variable that represents the exception that has occurred as well as other implicit variables. It can then send some message understandable by the clients, by consulting those objects.
1.2. include directive
This directive inserts the content of a file in a JSP page, during the translation phase when the JSP page is compiled.
Syntax:
<%@ include file=”relativeURL” %>
If the file to be included is an HTML or text file, its content is directly included in the place of the include directive. The following example includes an HTML file header.html in a JSP page.
<%@ include file=”header.html” %>
If the included file is a JSP file, it is first translated and then included in the JSP page.
<%@ include file=”login.jsp” %>
Make sure that the tags in the included file do not conflict with the tags used in including the JSP page. For example, if the including JSP page contains tags such as <html> and <body>, the included file must not contain those tags.
The include process is said to be static as the file is included at compilation time. JSP 1.1 specifies that once the JSP file is compiled any changes in the included file will not be reflected. However, some JSP containers, such as tomcat, recompile the JSP page if the included file changes.
2. Comments
Comments are used to document the JSP pages and can be inserted anywhere in the JSP page. The general syntax is as follows:
<%– JSP comment –%>
Anything between <%— and —%> is ignored by the JSP engine and is not even added to the servlet’s source code. Here is an example:
<%– Prints current date and time –%>
<%= new java.util.Date(); %>
The Java-like comments may also be used in scriptlets and declarations. They are added to the servlet, but not interpreted and hence are not sent to the client.
<%
//get all cookies
Cookie[] cookies = request.getCookies();
/*
Following code checks whether the request contains a cookie having name “user”
*/
String user = null;
for(int i = 0; i < cookies.length; i++)
if(cookies[i].getName().equals(”user”)) user = (String)cookies[i].getValue(); if(user != null) {
//proceed
}
%>
The HTML comments are enclosed in <!– and –> and added to the servlet source code as well as to the response, but browsers do not display them on the screen. Consider the following code:
<!– This page was generated at server on
<%= (new java.util.Date()) %>
–>
This generates the following HTML comment. This is sent to the client, but not displayed on the screen.
<!– This page was generated at server on
Sun Sep 22 04:14:07 PDT 2013 –>
3. Expressions
JSP 2.0 specification includes a new feature, Expression. It is used to insert usually a small piece of data in a JSP page, without using the out.print() or out.write() statements. It is a faster, easier, and clearer way to display the values of variables/parameters/expressions in a JSP page. The general syntax of JSP expressions is as follows:
<%= expressions %>
The expression is embedded within the tag pair <%= and %>. Note that no semicolon is used at the end of the expression. The expression is evaluated, converted to a String and inserted in the place of the expression using an out.print() statement. For example, if we want to add 3 and 4 and display the result, we write the JSP expression as follows:
3 + 4 = <%= 3+4 %>
The expression is translated into the following Java statements in servlet source code.
out.write(”3 + 4 = ”);
out.print( 3+4 );
If everything works fine, you should see the following output:
3 + 4 = 7
The expression can be anything, as long as it can be converted to a string. For example, the following expression uses a java.util.Date object.
Date and time is : <%= new java.util.Date() %>
JSP expressions can be used as attribute values as well as tag names of JSP elements. Consider the following JSP code.
<%
java.util.Date dt = new java.util.Date();
String dateStr = dt.toString();
String time = ”currentTime”;
%>
<<%= time %> value=”<%= dateStr %>” />
This generates the following tag:
<currentTime value=”Sun Sep 22 04:12:50 PDT 2013” />
JSP also has an equivalent tag for expression as follows:
<jsp:expression>
expressions
</jsp:expression>
4. Scriptlets
You can insert an arbitrary piece of Java code using the JSP scriptlets construct in a JSP page. This code will be inserted in the servlet’s _jspService() method. Scriptlets are useful if you want to insert complex code which would otherwise be difficult using expressions. A scriptlet can contain any number of variables, class declarations, expressions, or other language statements. Scriptlets have the following form:
<% scriptlets %>
For example, the following scriptlet inserts the current date and time in the JSP page.
<%
java.util.Date d = new java.util.Date();
out.println(”Date and time is : ” + d);
%>
The resultant servlet code looks like this:
…
public final class scriptlet_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
public void _jspService(final javax.servlet.http.HttpServletRequest request,
final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
…
java.util.Date d = new java.util.Date();
out.println(“Date and time is : ” + d);
…
This results in the following:
Date and time is : Sun Sep 22 04:15:50 PDT 2013
JSP also has the following XML equivalent for scriptlet:
<jsp:scriptlet>
scriptlets
</jsp:scriptlet>
4.1. Conditional Processing
Several scriptlets and templates can be merged, to do some designated task. The following example illustrates this:
<%
int no = (int)(Math.random()*10); if(no % 2 == 0) {
%>
Even
<% } else { %>
Odd
<% } %>
This code gets converted into something like
int no = (int)(Math.random()*10);
if(no % 2 == 0)
{
out.write(”\r\n”);
out.write(”Even\r\n”);
} else {
out.write(”\r\n”);
out.write(”Odd\r\n”);
}
5. Declarations
JSP declarations are used to declare one or more variables, methods, or inner classes, which can be used later in the JSP page. The syntax is as follows:
<%! declarations %>
Examples are
<%! int sum = 0; %>
<%! int x, y , z; %>
<%! java.util.Hashtable table = new java.util.Hashtable(); %>
These variable declarations are inserted into the body of the servlet class, i.e., outside the _ jspService() method that processes the client requests. So, variables declared in this way become instance variables of the underlying servlet.
<%! int sum = 0; %>
This is translated in the servlet as follows:
…
public final class scriptlet_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent {
int sum = 0;
…
public void _jspService(final javax.servlet.http.HttpServletRequest request,
final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
…
Note that variables created using scriptlets are local to the _jspService() method. Instance variables are created and initialized once the servlet is instantiated. This is sometimes useful, but sometimes not desirable. The following declarations create an instance variable, lastLoaded.
<%! java.util.Date lastLoaded = new java.util.Date();%>
The servlet was last loaded on <b><%=lastLoaded%></b>
This generates the following result:
The servlet was last loaded on Sun Sep 22 04:19:12 PDT 2013
Similarly, the following piece of code displays the number of times the JSP page is referred after the page is loaded.
<%! int count = 0;%>
This page is referred <%= ++count %> times after last modification
Variables generated using declarations are available in scriptlets. A declaration has the scope of entire translation unit. It is valid in the JSP file as well as in all the files included statically. Declarations are not valid in dynamically included files.
JSP also has the following XML equivalent for declaration:
<jsp:declaration>
declarations
</jsp:declaration>
6. Scope of JSP Objects
In a JSP page, objects may be created using directives, actions, or scriptlets. Every object created in a JSP page has a scope. The scope of a JSP object is defined as the availability of that object for use from a particular place of the web application. There are four object scope: page, request, session, and application.
page
Objects having page scope can be accessed only from within the same page where they were created. JSP implicit objects out, exception, response, pageContext, config, and page have page scope. We have discussed implicit objects in the next section. JSP objects created using the <jsp:useBean> tag also have page scope.
request
A request can be served by more than one page. Objects having request scope can be accessed from any page that serves that request. The implicit object request has the request scope.
session
Objects having session scope are accessible from pages that belong to the same session from where they were created. The session implicit object has the session scope.
application
JSP objects that have application scope can be accessed from any page that belong to the same application. An example is application implicit object.
7. Implicit Objects
Web container allows us to directly access many useful objects defined in the _jspService() method of the JSP page’s underlying servlet. These objects are called implicit objects as they are instantiated automatically. The implicit objects contain information about request, response, session, configuration, etc. Some implicit objects are described in Table 21.2:
request
This object refers to the javax.servlet.http.HttpServletRequest type object that is passed to the _jspService() method of the generated servlet. It represents the HTTP request made by a client to this JSP page. It is used to retrieve information sent by the client such as parameters (using the getParameter() method), HTTP request type (get, post, head, etc), and HTTP request headers (cookies, referrer, etc). This implicit object has request scope.
<%
String name = request.getParameter(“name”);
out.println(”Hello ” + name);
%>
For the URL http://127.0.0.1:8080/net/getParameterDemo.jsp?name=Monali, it displays the following:
Hello Monali
A JSP page can retrieve parameters sent through an HTML form. Consider the following form:
<form method=’post’ action=’jsp/add.jsp’>
<input type=’text’ name=’a’ size=’4′>+
<input type=’text’ name=’b’ size=’4′>
<input type=’submit’ value=’Add’>
</form>
Here is the code for the add.jsp file.
<%
int a = Integer.parseInt(request.getParameter(”a”));
int b = Integer.parseInt(request.getParameter(”b”));
out.println(a + ” + ” + b + ” = ” + (a + b));
%>
The result is shown in Figure 21.6:
response
This object refers to the javax.serviet.http.HttpServietResponse type object that is passed to the _jspService() method of the generated servlet. It represents the HTTP response to the client. This object is used to send information such as HTTP response header and cookies. This implicit object has page scope.
pageContext
This javax.serviet.jsp.PageContext type object refers to the current JSP page context. It is used to access information related to this page such as request, response, session, application, and underlying servlet configuration. This implicit object has page scope.
session
This javax.serviet.http.HttpSession type object refers to the session (if any) used by the JSP page. Note that no session object is created if the session attribute of the page directive is turned off and any attempt to refer to this object causes an error. It is used to access session-related information such as creation time and ID associated to this session. This implicit object has session scope.
application
This javax.servlet.ServletContext object refers to the underlying application and is used to share data among all pages under this application. This implicit object has application scope.
out
It denotes the character output stream that is used to send data back to the client. It is a buffered version of java.io.PrintWriter called javax.servlet.jsp.JspWriter type object. The object out is used only in scriptlets. This implicit object has page scope.
<% out.println(“Hello World!”); %>
JSP expressions are placed in the output stream automatically and hence we do not use this out object there explicitly.
600 advanced java programming
config
This javax.serviet.ServietConfig type object refers to the configuration of the underlying servlet. It is used to retrieve initial parameters, servlet name, etc. This implicit object has page scope.
page
This object refers to the JSP page itself. It can be used to call any instance of the JSP page’s servlet. This implicit object has page scope.
exception
This represents an uncaught exception, which causes an error page to be called. This object is available in the JSP page for which the isErrorPage attribute of the page directive is set to true. This implicit object has page scope.
8. Variables, Methods, and Classes
Variables, methods, and classes can be declared in a JSP page. If they are declared in the declaration section, they become part of the underlying servlet class. For example, variables declared in the declaration section become instance variables and are accessible from any method of the JSP page’s servlet class.
Consider the following variable declaration:
<%! double PI = 22/7.0; %>
The resultant servlet code will look like this:
…
public final class method_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
double PI = 22/7.0;
…
These variables are also shared among multiple threads. Classes and methods can be declared in a similar way as follows:
<% !
int add(int a, int b) {
return a + b;
}
class AnInnerClass {
}
%>
The resultant servlet source code will look like this:
…
public final class method_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
int add(int a, int b) {
return a + b;
}
class AnInnerClass {
}
…
Variables, methods, and classes declared in the declaration section are available in scriptlets. So, the following scriptlet is valid for this declaration.
<%out.println(add(2, 3));%>
It displays the following:
5
JSP allows us to declare variables and classes, but not methods, in the scriptlet section. Variables declared in the scriptlet section are local to the _jspService() method. They are created each time the client makes a request and destroyed after the request is over. Similarly, classes declared in the scriptlet section become inner classes of the _jspService() method. Consider the following code:
<%
double temp = 0;
class TempClass {
}
%>
The resultant servlet code looks like this:
public final class method_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
public void _jspService(final javax.servlet.http.HttpServletRequest request,
final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
double temp = 0;
class TempClass {
}
8.1. Synchronization
Note that variables declared in the declaration section become instance variables. Instance variables become shared automatically among all request handling threads. You must handle synchronization issue to access these variables. Consider the following piece of code:
<%!int n = 1;%>
<%
for (int i = 0; i < 5; i++){
out.println(”Next integer: ” + n++ + ”<br>”);
Thread.sleep(500);
}
%>
The code is intended to print five consecutive integers. Each time this JSP page is invoked, it increments the instance variable n five times and displays the value. The code segment works fine if only one request is dispatched to this JSP page at a time. However, if two or more requests are sent to this JSP page, the result is not displayed correctly. To demonstrate this and to allow collision, a delay is given between two consecutive out.printin(). A sample output is shown in Figure 21.7: , if two requests are sent simultaneously.
One of the solutions of this problem is to make the for loop atomic so that only one request can access it at a time.
<% !
int n = 1;
Object o = new Object();
%>
<%
synchronized(o) {
for (int i = 0; i < 5; i++) {
out.println(”Next integer: ” + n++ + ”<br>”);
Thread.sleep(500);
}
}
%>
Another way to solve this problem is to inform the JSP container that this page is not thread-safe, so that the container dispatches requests one by one.
<%@ page isThreadSafe=”false” %>
<%!int n = 1; %>
<%
for (int i = 0; i < 5; i++){
out.println(“Next integer: ” + n++ + “<br>”);
Thread.sleep(500);
}
%>
In either case, the result will be correct.
9. Standard Actions
The JSP engine provides many built-in sophisticated functions to the programmers for easy development of the web applications. These functions include instantiating objects in a JSP page, communicating with other JSP pages and servlets, etc. JSP actions are nothing but XML tags that can be used in a JSP page to use these functions.
Note that the same thing can be achieved by writing Java code within scriptlets. However, JSP action tags are convenient ways to use those functions. They also promote component framework as well as application maintainability. The following section describes the commonly used JSP action tags.
include
This action tag provides an alternative way to include a file in a JSP page. The general syntax of the include action tag is
<jsp:include page=”relativeURL | <%=expression%>” flush=”true” />
For example, the following code includes the file header.jsp in the current page:
<jsp:include page=”header.jsp” />
It is similar to the include directive but instead of inserting the text of the included file in the original file at compilation time, it actually includes the target at run-time. It acts like a subroutine where the control is passed temporarily to the target. The control is then returned to the original JSP page. The result of the included file is inserted in the place of <jsp:include> action in the original JSP page. Needless to say, the included file should be a JSP file, servlet, or any other dynamic program that can process the parameters. The optional attribute flush can only take the value true.
Let us illustrate with an example. Suppose the content of date.jsp is as follows:
Date and time: <%= new java.util.Date() %>
Now, consider the file inciude.jsp, which has included the date.jsp file using the <jsp:inciude> action tag as follows:
Before<br>
<jsp:include page=”date.jsp” />
<br>After
This generates the following result:
Before
Date and time: Wed Dec 02 19:56:54 1ST 2009
After
In jspService() method, the following code is inserted:
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
…
out.write(”Before<br>\r\n”);
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, “date.jsp”, out, false); out.write(”\r\n”); out.write(”<br>After”);
The value of the page attribute may be a dynamically generated file name. The following example illustrates this:
<%
String fileName = ”sortByName.jsp”;
String criteria = request.getParameter(”sortCriteria”);
if(criteria != null) fileName = criteria + ”.jsp”;
%>
<jsp:include page=”<%=fileName%>” />
So, if the inciude.jsp page is invoked using the URL http://127.0.0.1:8080/net/include. jsp?sortCriteria=sortByRoii, the include action effectively becomes:
<jsp:include page=”sortByRoll.jsp” />
Note that the file sortByRoii.jsp must exist. Otherwise, an exception will be thrown. If the inciude.jsp page is invoked using the URL http://127.0.0.1:8080/net/include.jsp, the include action effectively becomes
<jsp:include page=”sortByName.jsp” />
param
The JSP <jsp:param> action allows us to append additional parameters to the current request. The general syntax is as follows:
<jsp:param name=”parameterName” value=”parameterValue | <%=expression%>” />
The name and value attributes of the <jsp:param> tag specify the case sensitive name and value of the parameter, respectively.
It is typically used with the <jsp:inciude> and <jsp:forward> action tags. For example, the following code passes the control to the JSP page process.jsp temporarily, with two additional parameters, user and sessionid.
<jsp:include page=”process.jsp”>
<jsp:param name=”user” value=”monali” />
<jsp:param name=”sessionId” value=”12D43F3Q436N43″ />
</jsp:include>
The value of the value attribute may be a dynamic value, but the value of the name attribute must be static. The following example illustrates this:
<% String user = request.getParameter(”user”); %>
<jsp:include page=”process.jsp”>
<jsp:param name=”user” value=”<%=user%>” />
<jsp:param name=”sessionId” value=”<%=System.currentTimeMillis()%>” />
</jsp:include>
forward
This action tag hands over the current request to the specified page internally at the server side. If the current page has already generated any output, it is suppressed. The output will only be caused by the page that has handled the request last in the forward chain. The control is never returned to the original page. The general syntax of the JSP forward action tag is
<jsp:forward page=”relativeURL | <%=expression%>” />
Consider the forward.jsp file, which forwards the current request to the date.jsp file using the <jsp:forward> action as follows:
Before<br>
<jsp:forward page=”date.jsp” />
<br>After
This transfers the control to the date.jsp page. The result the file forward.jsp has generated so far (Before<br> in our case) is cleared. The output is due to the page date.jsp only, as follows.
Date and time: Sun Sep 22 09:31:15 PDT 2013
Like the <jsp:include> action tag, the value of the page attribute of <jsp:forward> may be a dynamic file name. The following example illustrates this:
<% String mailbox = request.getParameter(”mailbox”) + ”.jsp”;%>
<jsp:forward page=”<%=fileName%>” />
Additional parameters may be specified using the <jsp:param> action as follows:
<%
String mailbox = request.getParameter(”mailbox”) + ”.jsp”;
String user = request.getParameter(”user”);
%>
<jsp:forward page=”<%=fileName%>” >
<jsp:param name=”user” value=”<%=user%>” />
<jsp:forward>
plugin
The <jsp:plugin> action is used to generate an HTML file that can download the Java plug-in on demand and execute applets or JavaBeans. It is an alternative way to deploy applets through Java plug-in. Since JSP pages are dynamic in nature, the developers of web applications can make use of Java plug-in to generate browser-specific tags to insert applets on the fly in a much easier and flexible way.
The <jsp:plugin> action generates the embed or object tag for the applet to be executed, depending upon the browser used. When the JSP is translated, the <jsp:plugin> action element is substituted by either an <embed> or an <object> HTML tag. The following code specifies an applet.
<jsp:plugin type=”applet” code=”Message” >
<jsp:params>
<jsp:param name=”message” value=”Hello World!”/>
</jsp:params>
<jsp:fallback>
<p> Unable to start Plug-in. </p>
</jsp:fallback>
</jsp:plugin>
The type attribute of the <jsp:piugin> tag specifies the type (bean or applet) of plug-in to be used and the code attribute specifies the name of the file (without extension) containing the byte code for this plug-in. In the above example, the <jsp:piugin> action inserts an applet whose code can be found in the class file Message.class.
The <jsp:piugin> action tag has a similar set of attributes as the <appiet> tag. The <jsp: params> and <jsp:param> actions are used to pass parameters to the plug-in. The <jsp:faiiback> tag specifies the message to be displayed if the Java plug-in fails to start due to some unavoidable reason.
Here is the source code for the Message applet (Message.java). public class Message extends java.applet.Applet {
String msg;
public void init() {
msg = getParameter(”message”);
}
public void paint(java.awt.Graphics g) { g.drawString(msg, 20, 20);
}
}
This applet takes a single parameter message and displays its value at location (20, 20) on the browser’s screen, relative to the applet window.
As mentioned earlier, the web server generates either an <embed> or an <object> tag, depending upon the browser that requested the JSP page. For example, the following code is generated if Tomcat 8.0 is used as the web server and Internet Explorer 8.0 makes the request.
<object classid=”clsid:8AD9C840-044E-11D1-B3E9-00805F499D93″
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=”Message”>
<param name=”type” value=”application/x-java-applet”>
<param name=”message” value=”Hello World!”>
<comment>
<EMBED type=”application/x-java-applet”
pluginspage=”http://java.sun.com/products/plugin/”java_code=”Message” message=”Hello World!”/>
<noembed>
<p> Unable to start Plug-in. </p>
</noembed>
</comment>
</object>
Though JSP specification includes the <jsp:piugin> action tag, different vendors may implement it differently. For detailed information, read the documentation of the web server.
useBean
It is used to instantiate a JavaBean object for later use. We shall discuss this action in Section 23.9.1 in detail.
setProperty
It is used to set a specified property of a JavaBean object. A detailed description of this action may be found in Section 23.9.2.
getProperty
It is used to get a specified property from a JavaBean object. This action has been discussed in Section 23.9.3 in detail.
10. Tag Extensions
One significant feature added in the JSP 1.1 specification is tag extension. It allows us to define and use custom tags in a JSP page exactly like other HTML/XML tags, using Java code. The JSP engine interprets them and invokes their functionality. So, Java programmers can provide application functionality in terms of custom tags, while web designers can use them as building blocks without any knowledge of Java programming. This way, JSP tag extensions provide a higher-level application- specific approach to the authors of HTML pages.
Though a similar functionality can be achieved using JavaBean technology, it lacks many features such as nesting, iteration, and cooperative actions. JSP tag extension allows us to express complex functionalities in a simple and convenient way.
10.1. Tag Type
JSP specification defines the following tags, which we can create and use in a JSP file.
Simple Tags
Tags with no body or no attribute. Example:
<ukr:copyright>
Tags with Attributes
Tags that have attributes but no body. Example:
<ukr:hello name=”Monali” />
Tags with Body
Tags that can contain other tags, scripting elements, and text between the start and end tags. Example:
<ukr:hello>
<%= name%>
</ukr:hello>
Tags Defining Scripting Variables
Tags that can define scripting variables, which can be used in the scripts within the page. Example:
<ukr:animation id=”logo” />
<% logo.start(); %>
Cooperating Tags
Tags that cooperate with each other by means of named shared objects. Example:
<ukr:tag1 id=”obj1” />
<ukr:tag2 name=”obj1” />
In this example, tagi creates a named object called obji, which is later used by tag2.
10.2. Writing Tags
In this section, we shall discuss how to define and use simple tags. The design and use of a custom tag has the following basic steps:
- Tag Definition
- Provide Tag Handler
- Deploy the tag
- Use the tag in the JSP file
Tag Definition
Before writing the functionality of a tag, you need to consider the following points:
- Tag Name—The name (and prefix) that will be used for the tag we are going to write
- Attributes—Whether the tag has any attribute and whether it is mandatory
- Nesting—Whether the tag contains any other child tag. A tag directly enclosing another tag is called the parent of the tag it encloses
- Body Content—Whether the tag contains anything (such as text) other than child tags
Provide Tag Handler
The functionality of a tag is implemented using a Java class called tag handler. Every tag handler must be created by directly or indirectly implementing the javax.serviet.jsp.tagext. Tag interface, which provides the framework of the JSP tag extension. In this section, we shall develop a simple tag named <ukr:heiio>, which has a single optional attribute, name. The <ukr:heiio> tag prints “Hello <name>“ or “Hello World!” depending upon whether the attribute name is specified or not.
Note that the tag <ukr:heiio> does not do much. It helps us understand the basic steps that we must follow to write a custom tag. In practice, custom tags will do complex tasks, but the procedure for developing such tags is exactly the same as the <ukr:heiio> tag. After creating the <ukr:heiio> tag, it is used in either of the following ways:
<ukr:hello name=”Monali” />
This prints “Hello Monali”.
<ukr:hello />
This prints “Hello World!”. Here is the complete source code for the hello tag handler (HeiioTag.
java).
package tag;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import java.io.IOException;
public class HelloTag extends SimpleTagSupport {
String name = “World!” ;
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.println(”Hello ” + name);
}
public void setName(String name) { this.name = name;
}
}
Though each tag handler must implement the javax.serviet.jsp.tagext.Tag interface, it is convenient to use one of the default implementations, the TagSupport or SimpieTagSuport class. Our tag is one without any body and hence we have used the SimpleTagSupport class. Each tag handler must define some predefined methods [Table 21.3:] that are called by the JSP engine. For example, the JSP engine calls the doStartTag() and doEndTag() methods when the start tag and the end tag, respectively, are encountered. The class SimpleTagSupport implements most of the work of a tag handler. The implementation of our class is simple, as it extends the SimpleTagSupport class. We have only implemented the doTag() method, which is called when the JSP engine encounters the start tag.
The hello tag has one attribute, name, whose value the handler must access. The JSP engine sets the value of an attribute xxx using the method setXxx() of the handler. This setXxx() method is invoked after the start tag, but before the body of the tag. So, we have inserted one method setName(), which will be used by the JSP engine to pass the value of the attribute name. Inside the handler, we have stored this value in a variable name. If a tag has multiple attributes, the corresponding tag handler must have separate set functions, one for each of these attributes.
Finally, we write the string “Hello” appended with the value of the name attribute to the servlet output stream. A reference to this output stream is obtained using the getOut() method on javax.
serviet.jsp.JspContext, which is returned by the getJspContext() method.
Deploy the Tag
Save this code in file HeiioTag.java and put it in the application’s /WEB-iNF/ciasses/tag directory. To compile this file, we need the necessary tag classes that are provided as the jar file jsp- api.jar. This jar file can be found in the lib directory of Tomcat’s installation directory. Make sure that this jar file is in your classpath during compilation. You can use the following command in the
/WEB-INF/classes/tag directory to compile the HelloTag.java file.
javac -classpath ../../../../../lib/jsp-api.jar HelloTag.java
This will generate the HelloTag.class file in the /WEB-INF/classes/tag directory. If everything goes fine, restart the web server. The tag class is now ready to use.
Now, we have to map the tag hello with this tag handler class, HelloTag. This is done in an XML file called Tag Library Descriptor (TLD). A TLD contains information about a tag library as well as each tag contained in the library. The JSP engine uses TLDs to validate tags used in the JSP pages. The Tag Library Descriptor is an XML document conforming to a DTD specified by Sun Microsystems.
We shall name our tag library file as tags.tld and put it in the application’s /taglib directory. For example, if the application’s root directory is net, put the tags.tld file in the /net/taglib directory. Make the following entry in the tags.tld file.
<?xml version=”1.0”?>
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>Simple tag library</short-name>
<tag>
<description>Prints Hello ‘name'</description>
<name>hello</name>
<tag-class>tag.HelloTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
Each <tag> element in the TLD file describes a tag. The <name> element specifies the name of the tag that will be used in the JSP file. The <tag-ciass> element associates the handler class with this tag name. In this case, the tag.HeiioTag class is the handler of the tag hello. Each <attribute> element specifies the attribute that can be used for this tag. Our tag can have only one attribute, name. The <required> element specifies whether the attribute is mandatory (true) or optional (false). A tag without a body must specify that its body-content is empty.
Use the Tag in the JSP File
The tag hello is now ready to use. Use the following entry in the JSP page tag.jsp and put it in the applications root directory, i.e., /net in our case.
<%@ taglib prefix=”ukr” uri=”/taglib/tags.tld” %>
<ukr:hello name=”Monali”/>
The taglib directive includes a tag library whose tags will be used by the JSP page. It must appear before using any custom tags it refers to. The uri attribute specifies a URI that uniquely identifies the TLD. The prefix attribute specifies the prefix to be used for every tag defined in this TLD. The prefix distinguishes tags in one library from those in others, if they contain tags with the same name. Now, write the following URL in the address bar of your web browser and press enter.
http://127.0.0.1:8080/net/tag.jsp
It displays
Hello Monali
For the following code
<%@ taglib prefix=”ukr” uri=”/taglib/tags.tld” %>
<ukr:hello />
The code
Hello World!
<%@ taglib prefix=”ukr” uri=”/taglib/tags.tld” %>
<%!String name=”Kutu”; %>
<ukr:hello name=”<%=name%>”/>
displays
Hello Kutu
11. Iterating a Tag Body
Sometimes, it is necessary to iterate a specific code several times. For example, suppose we want to generate a table containing integers and their factorial value. We can write scripts to do this, as follows:
<%
for(int i = 2; i <= 6; i++){
%>
<%=i%>!=<ukr:fact no=”<%=i%>” /><br>
<%
}
%>
We have assumed that there exists a tag handler for <ukr:fact> as follows:
package tag;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import javax.servlet.jsp.JspException;
import java.io.IOException;
import javax.servlet.jsp.JspWriter;
public class FactTag extends SimpleTagSupport {
int no;
public void doTag() throws JspException, IOException {
int prod = 1;
for(int j = 1;j <= no; j++) prod *= j;
JspWriter out = getJspContext().getOut();
out.println(prod);
}
public void setNo(int no) { this.no = no;
}
}
It would be better, if the same table uses the following code:
<ukr:FactTable start=”2″ end=”6″>
${count}! = ${fact}<br>
</ukr:FactTable>
We can reduce the amount of code in the scripting element by moving the flow of control to the tag handlers. The basic idea is to write a tag called iteration tags that iterates its body.
The iteration tag retrieves two parameters start and end. It calculates the factorial of each number between these two numbers (both inclusive) and assigns them to a scripting variable. The body of the tag retrieves the numbers and their factorials from scripting variables. Here is the handler for the iteration tag.
package tag;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import javax.servlet.jsp.JspException;
import java.io.IOException;
public class FactorialTag extends SimpleTagSupport {
int start, end;
public void doTag() throws JspException, IOException {
for(int i = start; i <= end; i++) {
int prod = 1;
for(int j = 1; j <= i; j++) prod *= j;
getJspContext().setAttribute(”count”, String.valueOf(i) );
getJspContext().setAttribute(”fact”, String.valueOf(prod) );
getJspBody().invoke(null);
}
}
public void setStart(int start) { this.start = start;
}
public void setEnd(int end) { this.end = end;
}
}
This handler, in each iteration, stores the value of the integer and its factorial in the count and fact variable, respectively, using the following code.
getJspContext().setAttribute(”count”, String.valueOf(i) );
getJspContext().setAttribute(”fact”, String.valueOf(prod) );
The body of the tag is iterated as follows:
getJspBody().invoke(null);
Now, make the following entry in the tags.tid file.
<?xml version=”1.0”?>
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>Simple tag library</short-name>
<tag>
<description>Calculates factorial from ‘start’ to ‘end'</description>
<name>FactTable</name>
<tag-class>tag.FactorialTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>start</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>end</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
Obtaining the factorial tables is now very simple. Consider the following code.
<%@ taglib prefix=”ukr” uri=”/taglib/tags.tld” %>
Factorial table<br>
<ukr:FactTable start=”2” end=”6”>
${count}! = ${fact}<br>
</ukr:FactTable>
In the body of the tag, the values of the count and fact variables are retrieved using expression language. Note that the JSP page does not contain a single piece of script. It is displayed as follows:
Factorial table
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
12. Sharing Data Between JSP Pages
All JSP pages participate in an HTTP session unless the session attribute of the page directive is set to false. An HTTP session is represented by the implicit object session. This session object has session scope and is thus shared among all the pages within the session.
This session object can be used as a shared repository of information such as beans and objects among JSP pages of the same session. For example, login.jsp page may store the user name in the session, while subsequent pages such as home.jsp can use it. Consider the code segment in login.jsp:
login.jsp:
String user = request.getParameter(”user”); session.setAttribute(”user”, user);
Now, see the code segment in home.jsp.
String user = (String)session.getAttribute(”user”);
Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.