Servlet


What are Servlets ?

Servlet - A Java program loaded and executed by the Web Server, in contrast to applets which are handled by a Web Browser. Hence servlets are called `server-side applets' [ Moss.2 ]

JSDK ( Java Servlet Development Kit ) - A part of JDK1.2 onwards [ Moss.4 ]

Advantages
  • Security as executed on web server behind optional firewall.
  • Persistent since loaded only once by the server, an advantage of transient CGI scripts.
  • Fast as need to be loaded once only.
  • Platform-Independant as written in Java.
  • Extensible since in Java. [ Moss.2-3 ]


Invoking Servlets from HTML

<html><body>
<form method="POST" 
         action="/servlet/properties" 
         enctype="x-www-form-encoded">
 <input name="input" 
         type="submit" 
         value="test servlet">
</body></html>
file.shtml [Moss.65]
<servlet name="servletname" code="servlet.class">
  codebase="codebase" init_param1="pvalue">
  <param name="pname" value="pvalue">
</servet>

SSI servlet invoked only if shtml suffix is requested.


Servlet Life-Cycle

  1. Servlet Invoker - URL: http://www.site.com/servlet/aservlet?arguments whereby /servlets (an alias of the servlet invoker) calls the servlet invoker.
  2. init() (optional) is called only once after loading, executed before other methods [ Moss.35 ]
  3. doGet(), doPost() - methods called for http get and post methods. Both methods are identical, which one is used depends on if http request used do or post method. "override one or both of the doGet and doPost methods." [ Moss.37 ]
  4. service() - Client requests are processed in the service method, each run in its own servlet thread. Servlets can thus run multiple service methods at a time [ Jserv ].
  5. destroy() is optional [ Moss.37 ]
hiworld.java
Illustrates the Steps of Servlet [ abrid. Moss.37-39 ]
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class hiworld extends HttpServlet
{
//  1. Override HttpServlet.doGet() and/or doPost() methods
   public void doPost(HttpServletRequest req, HttpServletResponse resp)
                      throws ServletException, IOException
   {
//  2. HttpServletResponse setContentType() is used 
      resp.setContentType("text/html");
//  3. java.io.PrintWriter writes response using HTTP output stream
      PrintWriter pw = new PrintWriter( resp.getOutputStream() );
        pw.println("<html><body>");
        pw.println("<h1> Hi World </h1>"
                 + "</body></html>");
        pw.close();
   }
}

Notes and Steps:


Session Tracking

Session Tracking - Managing a particular user acros multiple http requests via the stateles http, useful for shopping systems [ Moss.78 ]
track.java
Illustrates Session Tracking [ abrid. Moss.79-80, IBM.6-7 ]
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class track extends HttpServlet
{
   public void doGet(HttpServletRequest req, HttpServletResponse resp)
                      throws ServletException, IOException
   {
//  1. Get session object, create one if non-existent (true) 
      HttpSession hsess = req.getSession(true);
//  2. Get Number of Hits 
      Integer numofhits = (Integer) hsess.getValue("hitcount.txt");
        if (numofhits == null)
           { numofhits = new Integer(1); }
        else 
          numofhits += numofhits + 1;
//  3. Put incremented hit-value back  
      hsess.putValue("hitcount.txt",numofhits);
      PrintWriter pw = resp.getWriter();
      resp.setContentType("text/html");
        pw.println("<html><body>"+
                   "You have visited this page"+
                     numofhits + " times "
        pw.println("Your Session ID is : "+
                    hsess.getID();
                   "</html></body>");
        pw.close();
   }
}

Session Data Management

Cookies

cookies.java
Illustrates Cookies [ abrid. Moss.89 ]
import javax.servlet.*;
import javax.servlet.http.*;

public class cookies extends HttpServlet
{
   public void doGet(HttpServletRequest req, HttpServletResponse resp)
                      throws ServletException, java.io.IOException
   {
      Cookie cookys[] = req.getCookies();
      java.io.PrintWriter pw = resp.getWriter();
      resp.setContentType("text/html");
      pw.println("<html><body>");
      if ( ( cookys == null ) || ( cookys.length == 0 ) )
        {
         pw.println("No cookies found");
        }
      else 
        {
         pw.println("<h1> Cookies found </h1>");
         for (int i=0; i < cookys.length; i++ )
           {
           Cookie c = cookies[i];
           pw.println("<tr><td>"+c.getName()+"</td>"+ 
                         "<td>"+c.getValue()+"</td>"+
                         "<td>"+c.getComment()+"</td>"+
                         "<td>"+c.getMaxAge()+"</td></tr>"+
                         "</table></center>");
            }
         }
       pw.println("</body></html>");
   }
}

URL Rewriting

For those browsers without cookie support; session ID included in URL [ Moss.90 ]

Server-Side Includes

SSI ( Server-Side Includes ) - An SSI is a command or directive embedded in an html document. SSI permits embedding servlets within html documents using a <servlet> tag by means of a special internal servlet which processes this tag and using a special suffix-side mapping (.shtml being standard) [ Moss, p.64 ]
ssi.java
SSI Servlet [ abrid. Moss.71-72 ]
import javax.servlet.*;
import java.io.*;

public class ssi extends GenericServlet
{
//  1. Override service method 
  public void service(ServletRequest req, ServletResponse resp)
  {
   try{
      PrintWriter pw = new PrintWriter( resp.getOutputStream() );
      String pvalue = req.getParameterValue("pname");
      pw.println("<html>&`lt;body>");
      pw.println(""+pvalue+"");
      pw.println("</html></body>");
      }
   catch(ServletException se) { }
   catch(IOException ioe) { }
  }
}

ssi.shtml
SHTML file using SSI [ Moss.73 ]
<html><body>

<servlet code="javaservlets.samples.ssi">
  <param name="pname" value="Value of Parameter">
<servlet>

<p>
Then some text here.
</body></html>

Notes


Security

login.html
Password Prompting & Authentication [ abrid. Moss.107-10 ]
import javax.servlet.*;
import javax.servlet.http.*;

public class login extends HttpServlet
{
  public void doGet(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, java.io.IOException
   {
//  Force Server Loading instead of Cache Loading by Client 
    resp.setHeader("Expires","Tues, 01 Jan 1980 00:00:00 GMT");
//  Get Session User 
    HttpSession hsess = req.getSession(true);
    String suser = (String) hsess.getValue("users.txt");
    if (suser == null)
      { 
//  Force browser to prompt for login 
       resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
//  Following page displayed if user presses `Cancel' 
       pw.println("<html><body>"+
             "<h1> Invalid User </h1>"+ "<body><html>");
      }
   }

  protected String validUser(HttpServletRequest req)
  {
  // decoding operations from base64
  }

  protected boolean validateUser(String suser, String pwd)
  {
  boolean valid = false;
  if ( (suser !- null) && (pwd != null) ) 
    {
     if (user.equals("samar"))
      { 
       valid=true;
      }
    }
   return valid;
  }
}

SSL ( Secure Sockets Layer ) - Encryption system which sits on top of all socket communivation, encrypting outgoind data and decrypting incoming ones.


Applet-Servlet Communication

LoginApplet.java
Applet [ abrid. Moss.117f ]
import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;

public class LoginApplet extends Applet
{
  Label msg;
  public void init()
  {
  String servlet = getParameter("servlet");
  setLayout(new BorderLayout(0,5));

  Panel p = new Panel();
  TextField userfld = new TextField(10);
    p.add(userfld);
  TextField pwdfld = new TextField(10);
    pwdfld.setEchoCharacter('*');
    p.add(pwdld);
  Button b = new Button("Login");
    add("South",login);
  }

  public boolean handleEvent(Event e)
  {
  String user = userfld.getText();
  String pwd = pwdfld.getText();
  
  boolean valid = false;
  valid = validate_user(user, pwd);
  if (!valid)
   { msg.setText("Invalid User - try again."); }
  else 
   { msg.setText("Welcome, you are valid !"); }
  }

  protected boolean validate_user(String user, String pwd)
  {
  
  boolean valid  = false;
// Obtain servlet name which will validate password
  String codeBase = getCodeBase();
  String servlet = getParameter("servlet");
// Get Server URL
  java.net.URL url = new java.net.URL(codeBase + servlet);
// Attempt Connection to host
  java.net.URLConnection con = url.openConnection();
// Initialise connection
    con.setUseCaches(false);
    con.setDoOutput(true);
    con.setDoInput(true);

  ByteArrayOutputStream byteout = new ByteArrayOutputStream();
  DataOutputStream dout = new DataOutputStream(byteout);
  dout.writeUTF(hsessId);
// Send User and Password 
  dout.write(user);
  dout.write(pwd);
// Flush data to buffer 
  dout.flush():  
// some more steps left out
  DataInputStream din = new DataInputStream(con.getInputStream() );
  valid = din.readBoolean();
  if(valid)
    {
    nextDoc = din.readUTF();
    }
  din.close();
  return valid;
  }

}

Notes

Tunneling - Method of using the stateless HTTP to make remote calls over the internet in contrast to RMI, which uses TCP/IP. [ Moss.213 ]

TunnelApplet.java
Tunneling Applet [ abrid. Moss.216f ]
import java.io.*;

public class TunnelApplet
{

  public static void main(String args[])
  {
  try{
// Get the server URL
  java.net.URL url = new java.net.URL(args[0]);
// Attempt to connect to host and initialise connection
  java.net.URLConnection con = url.openConnection();
    con.setUseCaches(false);
    con.setDoOutput(true);
    con.setDoInput(true);
  ByteArrayOutputStream byteout = new ByteArrayOutputStream();
  DataOutputStream dout = new DataOutputStream(byteout);
    System.out.println("Writing test data ");
    dout.writeBoolean(true);
    dout.writeByte(1);
    dout.writeChar(2);
    dout.writeInt(4);
    dout.writeFloat(5);
    dout.writeDouble(6);
    dout.writeUTF("Hello, Karl");
    dout.flush();  // flush output to the buffer
// Get our output to be sent
    byte buf[] = byteout.toByteArray();
// Inform server of content type and length of data buffer
  con.setRequestProperty("Content-type application/octet-stream");
  con.setRequestProperty("Content-length "+buf.length);
// Get output stream to the server and send our data buffer
  DataOutputStream datout = new DataOutputStream(con.getOutputStream() );
    datout.write(buf);
    datout.flush();
    datout.close();
  System.out.println(" Reading response ");
  DataInputStream din = new DataInputStream(con.getInputStream() );
    boolean booleanval = din.readBoolean();
    byte byteval = din.readByte();
    char charVal = din.readChar();
    int intval = din.readInt();
    float flatval = din.readFloat();
    String strgval = din.readUTF();
    din.close();
  System.out.println(" Data read : "+ booleanval + byteval + 
     ( (int) charval ) + intval + floatval + doubleval + strgval 
    }
  catch(Exception e) { e.printStackTrace() ); }
  }
}

Notes

TunnelServlet.java
Tunneling Servlet [ abrid. Moss.218f ]
import java.io.*;

public class TunnelServlet
{

 public void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, java.io.IOException
  {
// Get the input stream 
  DataInputStream din = new DataInputStream(req.getInputStream());
// Create buffer
  ByteArrayOUtputStream byteaos = new ByteArrayOutputStream();
// Create the output stream to be used to write data to buffer
  DataOutputStream dout = new DataOutputStream(byteaos);
// Read data from client 
    boolean booleanval = din.readBoolean();
    byte byteval = din.readByte();
    char charval = din.readChar();
    int intval = din.readInt();
    float floatval = din.readFloat();
    double doubleval = din.readDouble();
    String stringval = din.readUTF();
// Write data to internal buffer
    dout.writeBoolean(booleanval);
    dout.writeByte(byteval);
    dout.writeChar(charval);
    dout.writeInt(intval);
    dout.writeFloat(floatval);
    dout.writeDouble(doubleval);
    dout.writeUTF(stringval);
// Flush contents of the output stream to the byte array
    dout.flush();
// Get buffer that is holding our response
  byte90 buf = byteOut.toByteArray();
// Notify client of how much data is being sent
  resp.setContentLength(buf.length);
// Send the buffer to the client
  ServletOutputStream servletout = resp.getOutputStream();
   servletout.write(buf);
   servletout.close();
  }
}

Notes


Serialisation

Serialisation - The process of storing (serialising) and retrieving (deserialising) the internal state of an object without having to be aware of the internal structure of that object. Used to enable RMI to pass objects between a client and server.


JDBC Servlets

The steps are the same as in ordinary JDBC. "Instead of printing the information to the standard output device (the console) we'll need to format the html that wil be sent back to the client." [ Moss.176 ]


JavaServer or Java WebServer

Services [Moss.11]

  • Web Service Standard http service set to default port 8080.
  • Sercure Web Service shttp (7070), only for licensed copies of JavaServer
  • Proxy (6060)
Internal Servlets [Moss.29]
  • Admin Servlet
  • CGI Servlet - replaces CGI.
  • File Servlet
  • Imagemap Servlet
  • Invoker Servlet invokes user-controlled servlet.
  • SSI Servlet


Automation

Reflection - The Reflection API (java.lang.relect) allows applications to inspect the internal makeup of other classes to obtain a list of constructors, methods an fields of any class and invoke methods in th fly. This is accomplished at run-time, so reflection is dynamic [ Moss.269 ].

Thus, using Reflection, process can be automated, eg. applet-servlet communication.


References


[ Index ]