6. JSP - Servlet Code
as generated by JSP Engine

Introduction

In the previous chapter we saw how the JSP engine first creates a servlet after adding the JSP code, compiles it and then finally executes it. As we have already laid the foundation for servlets, we will now try to gain in-depth knowledge of servlets, in the light of our newly acquired knowledge.

Let's now understand servlets. To do so, we will refer to our first script in the previous chapter.

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

You will see 'hi' displayed in your browser.

e1.jsp
hi

This Java file is located in one of the subdirectories of the work directory.
We explained the concept of servlets in one of the previous chapters. Let's understand the servlet code generated by the JSP engine by looking at smaller examples.

p1.java
import com.sun.jsp.runtime.*;
public class p1 extends HttpJspBase {
}
Here, there is only one public class called p1 that extends HttpJspBase. Since the class is called p1, you have no choice but to call the file p1.java. This program is in c:\jswdk-1.0.1\webpages\web-inf\servlets. The name of the class is not HttpJspBase but com.sun.jsp.runtime.HttpJspBase, therefore we have to use the import statement.

All code can be either in a .class file or in a .jar file. We have no choice but to point the environmental variable named classpath to the jar file or jar subdirectory so the compiler looks for the code there. A jar file is a collection of .class files. We have set the CLASSPATH to servlet.jar and jspengine.jar which are in the lib subdirectory and the current directory. To compile, we now say javac p1.java

Set CLASSPATH=c:\jswdk-1.0.1\lib\servlet.jar;c:\jswdk-1.0.1\lib\jspengine.jar;.;%CLASSPATH%

C:\jswdk-1.0.1\webpages\WEB-INF\servlets>javac p1.java
p1.java:2: class p1 must be declared abstract. It does not define void _jspService(javax.servlet.http.HttpServletRequest, avax.servlet.http.HttpServletResponse) from class com.sun.jsp.runtime.HttpJspBase.
public class p1 extends HttpJspBase {
^
1 error

HttpJspBase is an abstract class and has one function named _jspService. Since p1 extends HttpJspBase, p1 must define this class. Thus to eliminate the error, we must add this to our next program.

p1.java
import com.sun.jsp.runtime.*;
public class p1 extends HttpJspBase {
public void _jspService(HttpServletRequest request,HttpServletResponse response) {
}
}
C:\jswdk-1.0.1\webpages\WEB-INF\servlets >javac p1.java
p1.java:2: class p1 must be declared abstract. It does not define void _jspService(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse
) from class com.sun.jsp.runtime.HttpJspBase.
public class p1 extends HttpJspBase {
^
p1.java:3: Class HttpServletResponse not found.
public void _jspService(HttpServletRequest request,HttpServletResponse response
) {
^
p1.java:3: Class HttpServletRequest not found.
public void _jspService(HttpServletRequest request,HttpServletResponse response
) {
^
3 errors

_jspService is the same service that we have been using all this time. doGet and service both belong to the same category. This function takes two parameters, HttpServletRequest and HttpServletResponse. Hence we import javax.servlet.http.* and since we will be using PrintWriter in the program, we import java.io.* too. Now everything should work fine.

p1.java
import com.sun.jsp.runtime.*;
import javax.servlet.http.*;
import java.io.*;
public class p1 extends HttpJspBase {
public void _jspService(HttpServletRequest request,
HttpServletResponse response) {
try
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<b> Hi ");
out.close();
}
catch ( Exception e ) {System.out.println("bye");}
}
}

Run this program in the browser by typing
http://127.0.0.1:8080/servlet/p1

/servlet is converted to c:\jswdk-1.0.1\webpages\web-inf\servlets

This program now works like a servlet. A servlet will work in the same manner whether it is derived from Servlet or GenericServlet or HttpServlet or from HttpJspBaseServlet.

Having understood this, let's check out a more complex program.

p2.java
import java.io.*;
public class p2
{
public static void main(String argv[])
{
try {
char a[][] = {
{ 'a','b','c' },{ 'd','e','f' }};
FileOutputStream fos =
new FileOutputStream("c:\\jswdk-1.0.1\\webpages\\web-inf\\servlets\\e.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(a);
oos.close();
}
catch (Exception e)
{System.out.println("bye");e.getMessage();
}
}
}
C:\jswdk-1.0.1\webpages\WEB-INF\servlets>javac p2.java

C:\jswdk-1.0.1\webpages\WEB-INF\servlets>java p2

C:\jswdk-1.0.1\webpages\WEB-INF\servlets>dir *.dat

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

E DAT 73 06-13-00 8:28p e.dat
1 file(s) 73 bytes
0 dir(s) 2,651.09 MB free

C:\jswdk-1.0.1\webpages\WEB-INF\servlets>type e.dat
1/4_ -ur [[Cÿ2~+#i_- xp ur [C_&f__]ä1/4 xp a b cuq ~ d e f

Here, FileOutputStream creates a file named e.dat in the servlets subdirectory. Then we write 'abc' and 'def' in it. These two strings are written as chars to disk.

The next program follows up the previous one, which assumes that you have written an array of chars to the file e.dat. So in our next program, we are merely picking them up and displaying them. First we find out how many members are present in the file and then we display each of them.

p3.java
import java.io.*;
public class p3
{
public static void main(String argv[])
{
try
{
char a[][];int i;
FileInputStream fos = new FileInputStream("c:\\jswdk-1.0.1\\webpages\\web-inf\\servlets\\e.dat");
ObjectInputStream oos = new ObjectInputStream(fos);
a = (char [][] ) oos.readObject();
System.out.println(a.length);
for ( i=0; i<a.length;i++)
System.out.println(a[i]);
}
catch (Exception e){System.out.println("bye");e.getMessage();}
}
}

C:\jswdk-1.0.1\webpages\WEB-INF\servlets>javac p3.java

C:\jswdk-1.0.1\webpages\WEB-INF\servlets>java p3
2
abc
def

These small programs explain certain points required to understand the main program. So now let's understand the servlet written by the JSP engine.
p4.java
import javax.servlet.jsp.*;
import com.sun.jsp.runtime.*;
import javax.servlet.http.*;
import java.io.*;
import com.sun.jsp.JspException;
public class p4 extends HttpJspBase {
public void _jspService(HttpServletRequest request,
HttpServletResponse response) throws IOException,JspException {
JspFactory _jspxFactory = null;
PageContext pageContext = null;
JspWriter out = null;
try
{
_jspxFactory = JspFactory.getDefaultFactory();
pageContext = _jspxFactory.getPageContext(this, request, response,"", true, 8192, true);
out = pageContext.getOut();
response.setContentType("text/html");
out.print("<b>Hie.... ");
out.print(out.getBufferSize());
} catch (Throwable t) {
if (out.getBufferSize() != 0)
out.clear();
throw new JspException("Unknown exception: ", t);
} finally {
out.flush();
_jspxFactory.releasePageContext(pageContext);
}
}
}

Output in browser
Hie.... 8192

Run the above as

http://127.0.0.1:8080/servlet/p4

and compare the above code with that generated by the jsp engine. They are identical.

The JSP engine calls the _jspService function in the servlet for any task that is to be performed. Here, we first create an object _jspFactory that looks like JspFactory. JspFactory is a class and to use it we add two imports statements.

It is important to know which import statements are required for the classes used in the program. To avoid all these permutations and combinations, we have given all the imports that we think are appropriate._jspFactory is initialized to the return value of getDefaultFactory. JspFactory like System is a class. It has a static function getDefaultFactory, which returns an object that looks like JspFactory.
JspFactory has a member named getPageContext that manages a page. For the moment, we will leave the parameters aside. This function returns a pageContext which has a member named getOut, used for writing purposes. getOut returns an object that looks like JspWriter, which we store in out. Here, we have JspWriter instead of PrintWriter, but both are the same. out.println is used to write text and out also has one more function named getBufferSize. getBufferSize returns 8192 because that is the buffer size we have given in pageContent. If an error is encountered at any point then catch will be called.

Exception is derived from Throwable. The base class is Throwable and all exceptions are derived from it. We first check the buffer size and if it is not equal to 0, we clear the buffer. Anything in the buffer will now be over-written. Then we throw the exception jspException (we have imported com.sun.jsp.JspException.) After this has been done, out.flush will flush the buffer and releasePageContext will release the pageContext.

Here, JspWriter is performing the job of PrintWriter. Effectively, they are the same; there is no difference between them.

p5.java
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 p5 extends HttpJspBase {
static char[][] _jspx_html_data = null;
private static boolean _jspx_inited = false;
public final void _jspx_init() throws JspException {
ObjectInputStream oin = null;
int numStrings = 0;
try {
FileInputStream fin=new
FileInputStream("c:\\jswdk-1.0.1\\webpages\\web-inf\\servlets\\e.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]);
System.out.println(_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);
}
}
}

In this program, all that we have done is, within _jspService we have created 3 more objects, session, application and config. Like the earlier program, getPageContext returns pageContext. pageContext has a function which will create the respective object and then initialize session, application and config.

Before all this is done, the if statement checks whether _jspx_inited, a static variable, holds a true or false. The first time it holds false, so _jspx_init is called. This function has an object that looks like ObjectInputStream. We now open a file named e.dat which we created a little while ago. This entire file is read into _jspx_html_data, an array of chars, using FileInputStream. In case an error is encountered, an exception is thrown and finally, the file is closed. All this has been explained individually earlier, so we won't explain it again.

Once the function is called, _jspx_inited is made true so that the function is not called again. In the main code, there is an out.print for _jspx_html_data[0]. This is the only new statement added. This array had been initialized in _jspx_init with the contents of e.dat. So when you run this servlet, it will show you abc in the browser because jspx_html_data [0] is the first array and jspx_html_data [1] is the second array.


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