5. Java Server Pages

Introduction

Based on servlet technology, Java Server Pages (JSP) is one of the most important elements of Java server programming.

Java Server Pages combine HTML or XML with nuggets of Java code to produce dynamic web pages. Each page is automatically compiled to a servlet by the JSP engine the first time it is requested, and then executed. JSP provides a variety of ways to talk to Java classes, servlets, applets and the web server.

NOTE: We'll be explaining JSP using the Java Server Development Kit or the JSWDK which can be downloaded from Sun's site at www.javasoft.com. All new development on JSP/servlets has been passed on to the apache team. The reason we are teaching you the older version is because it is easier. There are cosmetic changes from the one we are doing to the jakarta version which we will go back to in the last chapter.

Download the zip file from the Sun site on the Internet and unzip it. It will create a sub directory jswdk-1.0.1. cd into this sub directory and then move into the bin sub directory. Here run a batch file named startserver. If you get an error in the Java Web Server window and if you are using jdk 1.2.2 like we are, add the following to the classpath variable.

set CLASSPATH=c:\jdk1.2.2\lib\tools.jar;%CLASSPATH%


A Simple Java Server Page

Let us begin by creating a simple jsp file. To do so, create a file that has a .jsp extension and save this file to the examples\jsp subdirectory. You can save it in the examples subdirectory or the jsp subdirectory, either is fine. We have named the file e1.jsp and it contains only one word, 'hi'.
e1.jsp
hi

Open this file in the browser by giving the url as
http://127.0.0.1:8080/examples/jsp/e1.jsp

'hi' will now be displayed in your browser window.

Congratulations! You have written the world's smallest JSP program. The browser initially takes a long time to show you the result but in future it will be very quick.

Now go to the subdirectory named work, where you will find a subdirectory ending with the word examples. Change to this directory.

C:\jswdk-1.0.1\work>dir

Volume in drive C is SONAL
Volume Serial Number is 0661-13EE
Directory of C:\jswdk-1.0.1\work

. <DIR> 06-05-00 7:31p .
.. <DIR> 06-05-00 7:31p ..
%3A808~1 <DIR> 06-05-00 7:31p %3A8080%2Fexamples
%3A808~2 <DIR> 06-05-00 7:31p %3A8080%2F
0 file(s) 0 bytes
4 dir(s) 2,629.67 MB free

C:\jswdk-1.0.1\work>cd %3A808~1


This is your first JSP file. You will find 3 files there, one java file, one class file and one dat file. If you look at their names, they are very long but they all contain e1.

C:\jswdk-1.0.1\work\%3A8080%2Fexamples>dir

Volume in drive C is SONAL
Volume Serial Number is 0661-13EE
Directory of C:\jswdk-1.0.1\work\%3A8080%2Fexamples

. <DIR> 06-05-00 7:31p .
.. <DIR> 06-05-00 7:31p ..
JSP_00~1 JAV 2,615 06-05-00 7:31p jsp_0005ce_00031_0002ejspe1_jsp_1.java

C_0003~1 DAT 59 06-05-00 7:31p C_0003a.
jswdk_0002d_00031_0005f_00030_0005f_00031.examples.jspe1.dat

C_0003A <DIR> 06-05-00 7:32p C_0003a

JSP_00~1 CLA 2,530 06-05-00 7:32p jsp_0005ce_00031_0002ejspe1.class

3 file(s) 5,204 bytes
3 dir(s) 2,629.66 MB free

C:\jswdk-1.0.1\work\%3A8080%2Fexamples>

Now open the java file by saying edit *.java

package C_0003a.jswdk_0002d_00031_0005f_00030_
0005f_00031.examples.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Vector;
import com.sun.jsp.runtime.*;
import java.beans.*;
import com.sun.jsp.JspException;
public class jsp_0005ce_00031_0002ejspe1_jsp_1 extends HttpJspBase {

static char[][] _jspx_html_data = null;

public jsp_0005ce_00031_0002ejspe1_jsp_1( ) {
}

private static boolean _jspx_inited = false;

public final void _jspx_init() throws JspException {
ObjectInputStream oin = null;
int numStrings = 0;
try {
FileInputStream fin = new FileInputStream("work\\%3A8080%2Fexamples\\C_0003a.
jswdk_0002d_00031_0005f_00030_0005f_00031.
examples.jspe1.dat");
oin = new ObjectInputStream(fin);
_jspx_html_data = (char[][]) oin.readObject();
} catch (Exception ex) {
throw new JspException("Unable to open data file");
} finally {
if (oin != null)
try { oin.close(); } catch (IOException ignore) { }
}
}

public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {

JspFactory _jspxFactory = null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
String _value = null;
try {

if (_jspx_inited == false) {
_jspx_init();
_jspx_inited = true;
}
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext(this, request, response,"", true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();

out.print(_jspx_html_data[0]);

} catch (Throwable t) {
if (out.getBufferSize() != 0)
out.clear();
throw new JspException("Unknown exception: ", t);
} finally {
out.flush();
_jspxFactory.releasePageContext(pageContext);
}
}
}

Edit shows you a Java program which has been created by the Java Web Server. The JSP file that you ran from the browser was converted into a servlet. The static data in the jsp file was stored in a new file with the .dat extension in the subdirectory work. The JSP engine writes this code for you. All your html code is stored in the file with the .dat extension. At first _jspx_init is called which opens the .dat file with the static text. Then _jspService is called. Now you know why it takes a long time for the output to show up in the browser. It takes some time to convert the jsp file into a servlet and then compile the servlet to a .class file and then run the servlet.

JSP Expressions

A JSP Expression is a great tool for embedding values within your HTML code. Anything between <%= and %> tags will be evaluated, converted to a string, and then displayed.

Now let's create another file where we start with hi and then send %="bye" %.

e2.jsp
hi
<%= "bye" %>
no

Partial Output of the servlet code generated by the jsp engine for the .jsp file is enclosed with the dotted lines..

----------------
out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e2.jsp";from=(1,3);to=(1,10)]
out.print( "bye" );
// end
out.print(_jspx_html_data[1]);
--------------------

When you view this file in your browser, it will display hi, bye and no, all on the same line.

Note that you must save the file as e2.jsp and not e1.jsp.

Let's understand what we have just done. The JSP engine takes over and it saves hi to disk in the .dat file. Then it sees the tag '<%'. It understands this character and for it anything within <% %> is JSP. A tag is anything that starts with an angle bracket. '<%' is also used in Active Server Pages. The '=' sign tells the engine to add the line 'out.print' in the Java program and also whatever is given in double quotes as a parameter to print. It automatically puts the open and close bracket and a semicolon at the end. The next line with 'no' is also saved to disk as another array.

In effect, you have saved two arrays of chars on disk. If you look at the code, it all looks the same. The only difference is that it says print the first array, then the newly added line, out.print("bye"), and then it finally print the second array.

_jspx_init uses the function readObject to read the contents of the .dat file into an array _jspx_html_data. Thus the array member _jspx_html_data[0] will contain hi and _jspx_html_data[1] will contain bye. out looks like JspWriter and is initialized in _jspService. It is used to create the html file which will be sent across.

e3.jsp
hi
<% out.println("no"); %>
bye

------------------
out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e3.jsp";from=(1,2);to=(1,22)]
out.println("no");
// end
out.print(_jspx_html_data[1]);
------------------

Now remove the '=' sign in the JSP file and write out.println ("no"); Since there is no '=' sign, the jspengine does not add its own out.print. This jsp statement gets added in as is. The JSP engine assumes it to be Java code. This means that if you do not write good Java code here, you will get horrible errors. This happens when javac compiles the Java program. They will be displayed in your Java server window.

This implies that whenever you put an '=' sign, you must use something that will be converted to a string in Java. This is because the out.print that is added takes only a single string as its parameter.

Hence bye is enclosed within double quotes. Try giving it without quotes and you will be presented with an error. The bye is assumed to be a variable. If you put a semicolon then it takes the semicolon as a part of the double quotes. There is supposed to be no space between the % and =. It must be typed in like this, <%=

In a nutshell, we have html code and then there are Java Server Pages, where we have html, and Java code within that html. The html tags and text are saved to disk and the Java code comes as is. Thus in a jsp program we get to mix html and java code. All the java code written so far can be placed in a jsp program along with html but within the <% tag.

e4.jsp
hi
<%= bye %>
no

Output in Browser
Error: 500
Unable to compile class for JSP

Error message in the java server window.
com.sun.jsp.runtime.JspServlet: init
Scratch dir for the JSP engine is: work\%3A8080%2Fexamples
IMPORTANT: Do not modify the generated servlets
Unhandled error! You might want to consider having an error page to report such
errors more gracefully
com.sun.jsp.JspException: Compilation failed:work\%3A8080%2Fexamples\jsp_0005ce_
00032_0002ejspe2_jsp_2.java:69: Undefined variable: bye
out.print( bye );
^
1 error

at com.sun.jsp.compiler.Main.compile(Main.java:347)
at com.sun.jsp.runtime.JspLoader.loadJSP(JspLoader.java:135)
at com.sun.jsp.runtime.JspServlet$JspServletWrapper.loadIfNecessary(JspS
ervlet.java:77)
at com.sun.jsp.runtime.JspServlet$JspServletWrapper.service(JspServlet.j
ava:87)
at com.sun.jsp.runtime.JspServlet.serviceJspFile(JspServlet.java:218)
at com.sun.jsp.runtime.JspServlet.service(JspServlet.java:294)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:840)
at com.sun.web.core.ServletWrapper.handleRequest(ServletWrapper.java:155
)
at com.sun.web.core.Context.handleRequest(Context.java:414)
at com.sun.web.server.ConnectionHandler.run(ConnectionHandler.java:139)

Here it assumed that bye was a variable and the error is detected by javac on compiling the servlet generated by the jsp engine.

Moving on to the next example, where we are now writing System.out.println("no") within the % tag.
e5.jsp
hi
<% System.out.println("no"); %>
bye

----------------
out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e5.jsp";from=(1,2);to=(1,29)]
System.out.println("no");
// end
out.print(_jspx_html_data[1]);
-----------------
Output in Server Window
no
There is no '=' following the %, so it is included as it is in the Java file. The 'no' will not be shown on your screen but in the server's dos box. To display something on the screen, you can't use System.out.println, instead you must use out.println.

If you carefully study the code, you will observe that there are seven variables created and one of them is out. Hence in JSP you are allowed to use out and you can use any of these seven variables in your program. These are the predefined objects available to you. System.out.println can also be used anywhere in a jsp tag as it is a valid java statement. Do not forget the terminating semicolon as java code written in a tag is added verbatim to the function _jspx_service().

JSP Declarations

A JSP declaration can be thought of as the definition of class level variables and methods that are to be used throughout the page.

In the next example, we have hi and then bye. The JSP code begins with int j preceded by an exclamation, and thereafter it has int i with a semicolon.

e6.jsp
hi
<%! int j; %>
bye
<% int i; %>

--------------------
public class jsp_0005ce_00036_0002ejspe6_jsp_1 extends HttpJspBase {
static char[][] _jspx_html_data = null;
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e6.jsp";from=(1,3);to=(1,11)]
int j;
// end

public jsp_0005ce_00036_0002ejspe6_jsp_1( ) {
}
-------------------
-------------------
out.print(_jspx_html_data[0]);
out.print(_jspx_html_data[1]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e6.jsp";from=(3,2);to=(3,10)]
int i;
// end
out.print(_jspx_html_data[2]);
-----------------------

Whenever anything is put in an exclamation it is called a declaration. This is done outside any function but within the class that is public. The line int j comes up when your class starts with {. Whenever you put any statement in <%, it is placed in jspservice and becomes local. It is visible from then onwards. If you want to make a variable global then use an exclamation. You can create functions and global variables in a class. Unlike C, where 'global' is applicable to the file, here it is limited to a class.

Now we will mix java with html code.
e7.jsp
hi
<% int i = 6;
if ( i == 6 ) %>
bye

---------------
out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e7.jsp";from=(1,2);to=(2,14)]
int i = 6;
if ( i == 6 )
// end
out.print(_jspx_html_data[1]);
-------------
At first, the variable i which is of type int is initialized to the value 6. Then the if statement checks to see if i == 6. The next line after the comments will print bye only if i holds the value 6, otherwise it will do nothing. Since the bye is pure html, we have to end the jsp tag and close the JSP scriptlet. The final code looks like this, if (i == 6) out.println ("bye"); What ever is given in <% %> is kept as it is while the html statements become part of the array of chars.

But what is the purpose of all this? This is a method of generating dynamic code. The Perl family of scripting languages generates the entire page. The focus is on Perl writing the entire html page whereas ASP, PHP, JSP opted to have an html page where the code would be inserted. In the html page, you can put ASP, PHP or Java code to give the page dynamism and free yourself of the tedium of trying to create every possible page the visitor must be shown by hand. The file that you are writing is an html file, which means you can use an existing html editor.

For Java Server Pages, servlets are the foundation. Normally, a web page has a static template i.e. things which are permenant. With JSP, you separate the static and the dynamic, and insert dynamism into a web page. We will also use beans extensively in the Java Server Pages and one of the chapters will explain to you how you can create your own custom tags.

A JSP page is a text-based document that describes how to process a request and create a response.

JSP pages in servlet classes are what Sun calls its web components and these pages are delivered by a JSP container. When you look at a JSP page, you will see 3 classes of scripting elements. These are declarations, scriptlets and expressions.

The following example has been taken from the Net from a great FAQ that we stumbled upon. We don't mind if you take our programs too. We have not mentioned any names here because there were too many brains behind it.
e8.jsp
<% for (int i = 1; i<= 4 ; i++) { %>
<H<%=i%>>Hello</H<%=i%>>
<% } %>
hi

The code looks complicated but you can easily understand it.

The for statement goes on four times. Since the for statement is not part of html, it is enclosed within the % and the angle brackets. The '{' bracket starts the for loop. The set of statements to be executed within the for is a combination of HTML and JSP. H is an html tag that stands for heading. Along with H is a number that displays the heading in a different format. We have not used a number directly because we want it to be the value of i. i is a variable initialized in the for loop. The <%= is used to display the value of i which is 1 as of now. Hence the tag becomes H1. Following this is Hello. To close the tag, the same rules are followed, the closing tag becomes </H1>. The '}' bracket within the % and the angle brackets is used to close the for loop. When i becomes 2, the statement will be <H2>Hello</H2> and the same follows for 3 and 4. This is how Hello can be seen in all 4 tags.

View the actual code in the Java file and you will realize that it is much easier to comprehend.

View Source

<H1>Hello</H1>

<H2>Hello</H2>

<H3>Hello</H3>

<H4>Hello</H4>

hi

-------------------
out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e8.jsp";from=(0,2);to=(0,34)]
for (int i = 1; i<= 4 ; i++) {
// end
out.print(_jspx_html_data[1]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e8.jsp";from=(1,5);to=(1,6)]
out.print(i);
// end
out.print(_jspx_html_data[2]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e8.jsp";from=(1,20);to=(1,21)]
out.print(i);
// end
out.print(_jspx_html_data[3]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e8.jsp";from=(2,2);to=(2,5)]
}
// end
out.print(_jspx_html_data[4]);

out.print(_jspx_html_data[0]);
for (int i = 1; i<= 4 ; i++) {
out.print(_jspx_html_data[1]);
out.print(i);
out.print(_jspx_html_data[2]);
out.print(i);
out.print(_jspx_html_data[3]);
}
out.print(_jspx_html_data[4]);
------------------

There are 5 sets of html data in the JSP file. The first one is blank, the second one is <h, the next one is >hello</h, the third set is > and then finally, there is hi. These are the different values assigned to the variables in the for loop.
_jspx_html_data[1] = <h
i 1,2,3,4
_jspx_html_data[2] = >hello</h
i 1,2,3,4
_jspx_html_data[3] = >
_jspx_html_data[4] = hi


If you look at e.dat, it shows data as 5.

dat file
5
-
<H
-
>Hello</H
-
>
-
-

Let's go one step further, give two hyphens after %. Whenever you start with a <%- and end it with -%>, it signals a comment.

e9.jsp
hi
<%- vijay mukhi -%>
bye

The good thing about comments is that they soon disappear. They are present only in your JSP file and will not be seen in the servlet. That's why we have written my name there, it doesn't show up. So whenever you want to include comments but hide them from the client, this is what you use. All this happens on the server, nothing comes over on to the client hence nobody knows of it. If you want normal comments, use the html comments which are given as <!- .

JSP Directives

A JSP Directive is a statement that gives the JSP engine information for the page that follows. Anything with a <%@ sign is called a Directive. In the following program, we have used a directive named page. The other possible directives in JSP1.0 are include and taglib.

e10.jsp
<%@ page info="vijay" %>

public String getServletInfo() {
return "vijay";
}


The compiler generates different kinds of code depending upon the directive you use. The effects are global. Here we say page info=vijay. A page is a directive and info is an attribute. The attribute is given a value; vijay in this case. On doing so, the JSP engine actually creates a function named getServletinfo and this function returns the value given to info i.e. vijay.

e11.jsp
hi
<%@ page import="java.applet.*" %>

-----------------
package C_0003a.jswdk_0002d_00031_0005f_00030_0005f_00031.examples.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Vector;
import com.sun.jsp.runtime.*;
import java.beans.*;
import com.sun.jsp.JspException;
import java.applet.*;
-------------

When you give import as an attribute and then look at the Java generated file, you will see that at the end of the imports, there is import java.applet.*. You don't have to put a semicolon. This means that if you are a referring to some Java code in some classes, you don't have to preface them i.e. give full names, you just put imports. In case you have more than one import, then separate them using commas, they will all be added at the end. If there are two similar imports, it is not considered an error. A point to be noted here is that if the match is found earlier in the file, then the import added by you is not used.

e12.jsp
hi
<%@ page extends="java.util.Dictionary" %>

--------------
public class jsp_0005ce_00031_00032_0002ejspe12_jsp_1 extends java.util.Dictionary {
---------------

Normally, extends is not used because by default every class extends HttpJspBase. But if you do so then HttpJspBase is replaced with java.util.Dictionary. At times, when you want to write complicated code then you can have a class that is derived from HttpJspBase, from which you can further extend your classes. You must derive from HttpJspBase or else you will end up with a load of errors.

e13.jsp
hi
<%@ page implements="java.util.Dictionary" %>


Implements follows the same rules as that of extends. The JSP engine adds a line to the class with implements. It gives an error and no java file is generated as in this case as well, Dictionary is a class not an interface.
e14.jsp
<%@ page buffer="1000" %>
hi

------------
pageContext = _jspxFactory.getPageContext(this, request, response,"",true,1024000, true);
---------

Since we have given the buffer as 1000, the getPageContext function makes the buffer parameter 1000KB i.e. 1000 multiplied by 1024. This is the amount of buffering space required. Buffering improves speed since its better to write a larger number of characters at one go than a small number many times.

You will have multiple requests being sent to your web server. You may want either one instance of the servlet or you may want 20 of them running at a time. If you want the servlet to create multiple instances of itself then you must give isThreadsafe=false. The default is true.
e15.jsp
<%@ page isThreadSafe="false" %>
<b>hi

---------------
public class jsp_0005ce_00031_00035_0002ejspe15_jsp_1 extends HttpJspBase implements SingleThreadModel
-----------------

By saying isThreadSafe=false, the JSP engine will implement SingleThreadModel and it can load multiple instances of the servlet instead of one. This class in that sense doesn't have any function prototypes and hence we don't have to add any code in the file. It can however, check to see if we have implemented certain interfaces.

e16.jsp
<%@ page session="false" %>
Bye

Most of these attributes have a default value of true or false, so you don't need to specify them. There is one more attribute named session. By default, session is true, so you see the session object in _jspservice function.

The following are the variables that are created in the _jspservice function:

JspFactory _jspxFactory = null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
String _value = null;

When you make the page session false, session that looks like HttpSession, is not created at all.

The next script has the contentType initialized to text/plain. By default, the value assigned to this attribute is text/html.

e17.jsp
<%@ page contentType="text/plain" %>
<b>Bye

----------
response.setContentType("text/plain");
----------

The tag b is not recognized by the browser anymore and thus we see <b> Bye in the browser. The Content type depends upon the file being sent over.

If you initialize IsErrorPage to true, it will actually create an object called exception that looks like Throwable. This is then initialized by the getAttribute function.

e18.jsp
<%@ page isErrorPage="true" %>
hi

-----------
Throwable exception=(Throwable) request.getAttribute("javax.servlet.jsp.jspException");
------------

The request variable is given to us as a parameter in the jspservice function. getAttribute takes one parameter which is a variable and returns a value. Instead of a variable we call it an attribute. This is used to initialize the new variable named exception which looks like jspException. The concept of exceptions has already been discussed in one of the previous chapters.

Import saves us the trouble of typing too much. Here we have a function named abc which has been defined in the public area. Thus the declaration or the exclamation sign has been used. Basically, it throws an IOException. The reason why we have page import=java.io* is because it is easier to say IOException than java.io.IOException. The minute the function abc is called, an exception will be thrown. Somebody has to be there to receive this exception.
e19.jsp
<%@ page errorPage="f1.jsp" %>
<%@ page import="java.io.*" %>
<html>
<%! void abc() throws IOException
{
throw new IOException("hi bye");
}
%>

<%
//try
//{
abc();
//}
//catch ( Exception e) {}
%>
</html>

If we stop here , in the browse we get the following error .
Error: 404
No detailed message

We start by using page directive errorPage, which is also an attribute and its value is a jsp file f1.jsp. If you look at the code you will realize that it throws new HandleErrorPageException, which has f1.jsp as a parameter. f1.jsp is your error page and because of this throw, it will now go to f1.jsp. In abc we have a throw, we throw an IOException. Since an exception is thrown, the catch in the servlet will catch it as the try and catch around abc have been commented out. The servlet catch has HandleErrorPageException, where the first parameter is f1.jsp and the last one is out. out is used to display output. t is throwable as a parameter to catch. If you look at f1.jsp, it has to start with isErrorPage=true and we use exception.printStackTrace to print where the exception took place.
f1.jsp
<%@ page isErrorPage="true" %>
<%
out.println("<pre>");
PrintWriter pw = response.getWriter();
exception.printStackTrace(pw);
out.println("</pre>");
%>

Output
java.io.IOException: hi bye
at C_0003a.jswdk_0002d_00031_0005f_00030_0005f_00031.
examples.jsp.jsp_0005ce_00031_00039_0002ejspe19_jsp_1.

abc(jsp_0005ce_00031_00039_0002ejspe19_jsp_1.java:23)
at C_0003a.jswdk_0002d_00031_0005f_00030_0005f_00031.
examples.jsp.jsp_0005ce_00031_00039_0002ejspe19_jsp_1.
_jspService(jsp_0005ce_00031_00039_0002ejspe19_jsp_1.java:82)
at com.sun.jsp.runtime.HttpJspBase.service(HttpJspBase.java:87)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:840)
at com.sun.jsp.runtime.JspServlet$JspServletWrapper.service(JspServlet.java:88)
at com.sun.jsp.runtime.JspServlet.serviceJspFile(JspServlet.java:218)
at com.sun.jsp.runtime.JspServlet.service(JspServlet.java:294)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:840)
at com.sun.web.core.ServletWrapper.handleRequest(ServletWrapper.java:155)
at com.sun.web.core.Context.handleRequest(Context.java:414)
at com.sun.web.server.ConnectionHandler.run(ConnectionHandler.java:139)

<pre>
</pre>

------------------
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e19.jsp";from=(3,3);to=(7,0)]
void abc() throws IOException
{
throw new IOException("hi bye");
}
// end

In _jspservice
out.print(_jspx_html_data[0]);
out.print(_jspx_html_data[1]);
out.print(_jspx_html_data[2]);
out.print(_jspx_html_data[3]);
// begin [file="C:\\jswdk-.0.1\\examples\\jsp\\e19.jsp";from=(8,2);to=(14,0)]

//try
//{
abc();
//}
//catch ( Exception e) {}
// end
out.print(_jspx_html_data[4]);
} catch (Throwable t) {
if (out.getBufferSize() != 0)
out.clear();
throw new HandleErrorPageException("f1.jsp", t, out);
} finally {
out.flush();
_jspxFactory.releasePageContext(pageContext);
}
------------

f1.jsp error page
-----------
out.print(_jspx_html_data[0]);
out.print(_jspx_html_data[1]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\f1.jsp";from=(1,2);to=(6,0)]

out.println("<pre>");
PrintWriter pw = response.getWriter();
exception.printStackTrace(pw);
out.println("</pre>");
// end
out.print(_jspx_html_data[2]);
-------------

exception.printStackTrace prints out the text. In this way you can have a separate page for error handling. All that you should do is create a page named anything.jsp and in every JSP page redirect the errors to it.

Within the try and catch is abc, so the code of abc will be called. You can have a 'try' and 'catch' within another 'try' and 'catch' pair, nested as many levels deep as you want. abc throws an IOException, so the exception will be called.
e19a.jsp
<%@ page errorPage="f1.jsp" %>
<%@ page import="java.io.*" %>
<html>
<%! void abc() throws IOException
{
throw new IOException("hi bye");
}
%>
<%
try
{
abc();
}
catch ( Exception e)
{
System.out.println("hi in exception");
}
%>
</html>

Now that we have uncommented the try and catch near abc, the earlier catch was not called and down in the web server window we see hi in exception, which proves that only the inner try catch was activated.

e20.jsp
hi
<%@ include file="aa.html" %>
Bye


C:\jswdk-1.0.1\examples\jsp>edit aa.html
in aa.html

-------------------
out.print(_jspx_html_data[0]);
out.print(_jspx_html_data[1]);
---------------
dat file
2
hi

Output in browser
hi in aa.html Bye

A @ in a JSP file signals a directive. The earlier examples had 'page', while in the program shown above, we use include. include takes a string which has to be filename which is aa.html here. e20.jsp contains hi, then the include and finally a bye. aa.html simply contains 'In aa.html'.

As always, your entire JSP is converted into a .dat file. Since it is on two lines, you will see only two prints in the Java file.

The point that we are trying to make is that the .dat file is made at the time of the creation of the servlet. This is called the Translation Phase. You can change aa.html, add some more text and then refresh the server. The new text within the html file will not be displayed because the .dat file isn't created again.

The only way to incorporate the new changes is by either recompiling the Java file or stopping and restarting the server.Stopserver deletes all the files in the work directory, so all the files are created from scratch when you want to view them.

There are two phases in JSP. One of them is the Translation Phase, which it happens only once. Then, the service function 'jspservice' is called for every request.

So far we have included a .html file, so now let's try it out with JSP.

e21.jsp
hi
<%@ include file="aa.jsp" %>
Bye
aa.jsp
no
<%= new java.util.Date() %>
lously

----------------
.java file for e21.jsp
out.print(_jspx_html_data[0]);
out.print(_jspx_html_data[1]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\aa.jsp";from=(1,3);to=(1,25)]
out.print( new java.util.Date() );
// end
out.print(_jspx_html_data[2]);
--------------------

There is no java file for aa.jsp.

dat file
3
hi
-
no
-
lousy


Bye

With this example you will realize that if you have JSP code in include, then all the JSP code will be put in the service function. Thus whenever you want something dynamic, create a JSP file and use it with the include directive. Now each time you click on refresh the date function will be reexecuted, so you see a different date and time every time.

Let's go one step further.

e22.jsp
hi
<jsp:include page="zz.jsp" flush="true" />
bye

zz.jsp
no
bad

We now have 2 java files created for the 2 jsp files.
---------------------
The java file for e22.jsp

out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e22.jsp";from=(1,0);to=(1,42)]
out.flush();
pageContext.include("zz.jsp");
// end
out.print(_jspx_html_data[1]);
-----------------
-----------------
The java file for zz.jsp
out.print(_jspx_html_data[0]);
-----------------

The first line in e22.jsp has hi and the second line is jsp:include page="zz.jsp" within angle brackets. If you notice there is no % sign like we had earlier. Such a line is called an 'action'. Each time you refresh the file, it gets the filename and requests the server for that file. Unlike the earlier example, this is dynamic.

When you see the generated java code, there is no data stored anywhere, so you check the .dat file. In the Java file, the array size is 2, for hi and bye, hence you see 0 and 1. pageContext.include is what the jsp:include is converted to in the Java file. It is this pageContext.include that regenerates the file each time. Now the problem with using include as an action is that you cannot have Java code with it and in addition, you cannot change headers and cookies.

e23.jsp
hi
<jsp:include page="a40.html" flush="true" />
bye

a40.html
bye

-----------------
out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e23.jsp";from=(1,0);to=(1,44)]
out.flush();
pageContext.include("a40.html");
// end
out.print(_jspx_html_data[1]);
------------------

In e23.jsp, the first line is hi. Then a40.html, which contains bye, is included. Now change 'bye' in the html file to 'over' and click on refresh. This time you will see over instead of bye. include here is an action.

In the next script, we have a new action called forward.

e24.jsp
hi
<jsp:forward page="cc.jsp" />
bye

cc.jsp
no
<%= new java.util.Date() %>
lousy

------------------
out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e24.jsp";from=(1,0);to=(1,29)]
if (true) {
out.clear();
pageContext.forward("cc.jsp");
return;
}
// end
out.print(_jspx_html_data[1]);
------------------

This example introduces a new action named forward. page=cc.jsp implies that we are sending a page with it. Hence every time you try to load e23.jsp, you will be forwarded to cc.jsp. Forward becomes pagecontext.forward in the Java file. This will simply go to the page mentioned. A valid question to ask here would be, 'will it come back to e23.jsp?' The answer is no. That's because the last line before the closing brace is a return. So whenever you have forward as an action, the file passed to pagecontext.forward becomes your active html file and everything else is forgotten.

Bear in mind that the http protocol is a stateless protocol. Each time you connect to the web server you are disconnected after you receive the page. So if you are on the Amazon.com site and you buy 6 books, moving from one page to the other, it becomes a session and this session has to be tracked. This is where the session object comes into use.

z.htm
<html>
<form action=e26.jsp>
<input type='text' name='aa'>
<input type='submit' value='click'>
</form>
</html>


e26.jsp
<%= request.getParameter("aa") %>

------------------
out.print(_jspx_html_data[0]);
// begin [file="C:\\jswdk-1.0.1\\webpages\\e26.jsp";from=(0,3);to=(0,31)]
out.print( request.getParameter("aa") );
// end
out.print(_jspx_html_data[1]);
--------------------

Run in browse is follows

http://127.0.0.1:8080/examples/jsp/z.html


If you write bye in the text box and click on the button you will see bye in the browser and in the address bar of the browser

http://127.0.0.1:8080/examples/jsp/e26.jsp?aa=bye

If you want to read data from a form, you can say request.getParameter("aa") where aa is some name that you have given in the form. This returns bye since that is what we typed in our text box. The form has an action which will execute the JSP code on the server when the user clicks on the submit button. This will bring up a new page with the url containing ?aa=bye. The JSP engine then sends the value 'bye' to be displayed on the screen.

When the button named submit is clicked, the browser will look for a tag named form and within that tag an attribute named action. It will then create a url with action and at the end add a ?. Now it takes all the input statements, figures out what you have written in them and converts then to a name value pair seperated by '=', like so
aa=bye

With JSP it is very easy to extract these values, thereby making it the preferred tool for Web programmers.

In the following example we have created two functions, one named jspInit and the other named jspDestroy.
e26.jsp
<%!
public void jspInit()
{
super.jspInit();
System.out.println("jspinit");
}
public void jspDestroy()
{
super.jspDestroy();
System.out.println("jspdestroy");
}
%>
hi

----------------
public class jsp_0005ce_00032_00036_0002ejspe26_jsp_1 extends HttpJspBase {
static char[][] _jspx_html_data = null;
// begin [file="C:\\jswdk-1.0.1\\examples\\jsp\\e26.jsp";from=(0,3);to=(11,0)]
public void jspInit()
{
super.jspInit();
System.out.println("jspinit");
}
public void jspDestroy()
{
super.jspDestroy();
System.out.println("jspdestroy");
}
// end
---------------
Whenever a class extends HttpJspBase, the service function within HttpJspBase is called. This service calls jspInit once and only once when the class is loaded or initialized. It is not like _jspservice, which is called multiple times. jspDestroy is called when the servlet is destroyed. We will need our own jspInit if we want to initialize our variables or if we want certain code to be executed only once and similarly jspDestroy can be used to release the memory used by variables or do anything at the end. But it is difficult to pin point as to when jspDestroy will be called. Super is used to call the code in the original class.

In the next script, we have response.sendRedirect and within the round brackets a url has been specified. The job of this function is to take you to the site that has been passed as a parameter. This page then becomes the active Page.

e27.jsp
<% response.sendRedirect("http://127.0.0.1:8080/examples/jsp/e9.jsp"); %>

Normally, one is not supposed to write anything before or after sendRedirect. But if you do write something, it will not be displayed.
e28.jsp
hi <p> bye
<% response.sendRedirect("http://127.0.0.1:8080/examples/jsp/e9.jsp"); %>
no <p> good

http://127.0.0.1:8080/examples/jsp/e9.jsp

The address bar in the browser also changes its url, which means that the browser asked for a new url.

Every http page starts with a header. Normally, it will be 200 OK. 200 is called the http status code. There are around 20 to 30 predefined status codes, where 200 means OK, 404 is file not found and so on. Redirection has a status code of 304. In the next script, we have response.setStatus.
e29.jsp
<%
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
response.setHeader("Location","/examples/jsp/e9.jsp");
%>

SC_MOVED_PERMANENTLY is a status code informing the browser to read the next header line because the file has been moved. The next line sets the header variable Location to a location or a url from where the file is to be picked up. When you use response.sendRedirect or you use setStatus the status code is sent over to the client with more information in the header. When this reaches the browser, the browser asks for the new file, which in our case is e9.jsp. Finally, the user sees e9.jsp.

Now let's take a case where we want the user to visit a certain page, barring which he will not be allowed to browse our site. It's like a login page and unless the user doesn't go there first, he can't browse through the rest of the site.
e30.jsp
<%@ page session="true" %>
login
<%
HttpSession s = request.getSession(true);
if ( s.getValue("EID") == null )
{
String s1 = (String ) response.encodeRedirectUrl("e31.jsp?Origin=e30.jsp");
System.out.println(s1);
response.sendRedirect(s1);
}
else
out.println("<h1>hi");
%>

e31.jsp
<%
session.putValue("EID","sonal");
String s1=(String)
response.encodeRedirectURL(request.getParameter("Origin"));
System.out.println("e31 " + s1);
response.sendRedirect(s1);
%>

Also see the output in the Java Web Server. In the browser it shows.
login
hi

Here we have two files, e30.jsp and e31.jsp. The directive, page session="true", is not required but we will retain it. Then we have login as the text to be displayed. s is a variable that looks like HttpSession and it is initialized to the return value of request.getSession. This function returns details of the current session. getSession will either create a new session or will return a handle to the current session. Of all the variables, we are currently interested in the value of the variable EID which you must put in capital letters. Since we haven't declared a variable named EID, it will be null for now.

response.encodeRedirectUrl will create a url of the string given within the brackets and return a string. This is stored in s1. response.sendRedirect will take you straight to e31.jsp

In e31.jsp, session.putValue creates the variable EID and initializes it to 'sonal'. request.getParameter will return the value of Origin, which is e30.jsp, and as previously mentioned response.encodeRedirectUrl will convert this into a url. Finally, there is a redirection to e30.jsp again. Within e30.jsp the value of EID is already set, which is why you will not see login again. Instead you see hi. This proves that both s and the session are the same.

What we are trying to say is that as long as it is the same user on the website, he will not have to login again, but if the user shuts down the browser and starts another copy, the entire process has to be repeated. The next program provides further insight into sessions.
e32.jsp
<%@ page session="true" %>
hi
<%
HttpSession s = request.getSession(true);
s.putValue("vij","sonal");
%>

e33.jsp
<%@ page session="true" %>
Bye
<%
HttpSession s = request.getSession(true);
%>
<%= s.getValue("vij") %>

In e32.jsp, we first write hi. request.getSession will return the current session handle which is stored in s. Then s.putValue will create 'vij' if not present and initialize it to 'sonal'.

The next page where we have bye is along the same lines as earlier. s is a handle to HttpSession. s.getValue of vij will return 'sonal'.

We first want you to run e33.jsp. Here, you will see bye and null because at the moment vij has no value. After doing so, run e32.jsp. You will see hi on this page and now once again reload e33.jsp. You will see 'sonal' displayed on your screen.

The point to be noted here is that there are two types of objects, implicit objects and explicit objects. Session and out are examples of implicit objects; they are already created. The explicit objects are not created by default, they have to be created and initialized. This is what you will learn in the next chapter.

Applets are not allowed to write data to disk but with servlets no such rules apply. The next example confirms this.
e34.jsp
<%@ page import="java.io.*" isErrorPage="true" %>
<%
try
{
PrintWriter p=new PrintWriter(new FileOutputStream("pp.txt"));
p.println("hi");
p.close();
}
catch ( Exception e) {
e.printStackTrace();
}
%>

C:\jswdk-1.0.1>dir pp.txt

Volume in drive C is SONAL
Volume Serial Number is 0661-13EE
Directory of C:\jswdk-1.0.1

PP TXT 4 06-13-00 3:15p pp.txt
1 file(s) 4 bytes
0 dir(s) 2,652.13 MB free

C:\jswdk-1.0.1>type pp.txt

hi

FileOutputStream is used when you want to open a particular file in output mode i.e. for writing. Since the file named pp.txt is not present on the disk, it will first be created. To write to this file you need a handle to it. new PrintWriter will return a handle to this file, so p now becomes a pointer to pp.txt. We then say p.println ("hi") which will write the text 'hi' to the file. You can give the complete path along with the filename, or use the default which is the jswdk-1.0.1 subdirectory. If you want to read from a file then use FileInputStream instead of FileOutputStream.
When you execute the command 'type pp.txt' in c:\jswdk-1.0.1, it will print hi on the screen.

For the grand finale of this chapter, we have one last example.

The web-inf directory has a file named servlet.properties. This example prints the properties and their values within this file. We had done something similar in the servlet chapter. We have not shown you the contents of this file as it will obviously differ on your machine.
e35.jsp
<%@ page import="java.util.*" %>
<%!
ServletConfig cfg;
public void jspInit()
{
cfg = getServletConfig();
for ( Enumeration e = cfg.getInitParameterNames(); e.hasMoreElements();){
String name = (String) e.nextElement();
String value = cfg.getInitParameter(name);
System.out.println(name+"="+value);
}
}
%>

keepgenerated=true

servlet.properties has things like keepgenerated=true. This property, if it is true, will not delete the Java code from the work directory once it has been created and compiled.

Normally, when you have errors, you would like them to be displayed on your web page and not on the console of the web server. To do so, you say setErrorToClient=true. The client will now see the errors in his browser. They will now nolonger be displayed on the server console.

In our program, getServletConfig allows us to find the parameters that have been set by the Java Web Server. This returns an object that looks like ServletConfig(). cfg.getInitParameterNames() returns an enumeration which in turn has a member hasMoreElements. e.nextElement gives us the name of the element and getInitParameter along with the name will tell us its value. Thus, they are all stored as a name-value pair. Since we only have one property at the moment, it will display keepgenerated and its value true and then the for loop will terminate.

Conclusion

Java Server Pages bring together the power of Java Servlets and HTML coding thereby give the developers a powerful method to create Server-Side web applications. In this chapter, we learnt the following:

A Java Server Page file consists of HTML tags, content, JSP directives, JSP declarations, JSP scriptlets and action tags. Initially, the JSP engine parses the JSP file which then generates a new servlet with the desired content. If the file changes, then a new servlet is generated; otherwise, the compiled version is used.


Contents | Foreword | About the Authors | Introduction |
Appendix |Chapter 1 |Chapter 2 |Chapter 3 |Chapter 4 |Chapter 5 |Chapter 6 |
Chapter 7 |Chapter 8 |Chapter 9 |Chapter 10 |Chapter 11