22
Core Servlets Chapter 3 Link for Core Servlets code: http://volume1.coreservle ts.com/archive/

Core Servlets Chapter 3 Link for Core Servlets code: om/archive/ om/archive

  • View
    259

  • Download
    3

Embed Size (px)

Citation preview

Core Servlets Chapter 3

Link for Core Servlets code:http://volume1.coreservlets.com/archive/

The purpose of servlets

• Servlets are a middle layer between the client and applications on the HTTP server like database access, legacy applications, java programs, and web services.

• In Java, these applications have names like JDBC, JNI, RMI, and SOAP.

Steps or phases1. Read explicit data from client: The end user enters data, usually

in an HTML form. Data could also come from an applet or custom HTTP program.

2. Read the implicit HTTP request data sent by the browser. This includes cookies, media types and compression schemes the browser can handle.

3. Generate the result. This may mean talk to a database, execute an RMI or CORBA call, invoke a web service, etc. and then to embed the results into a document.

4. Send the explicit data to the client. This may be text, XML, HTML, binary and so on.

5. Send the implicit HTTP response data. This includes information on the type of document being returned, setting cookies, caching parameters and so on.

Servlet Structureimport java.io.*;import javax.servlet.*;import javax.servlet.http.*;

public class ServletTemplate extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //use request object to read HTTP headers, cookies, query string//use response object to specify HTTP response status code and headers // (eg., content type, cookies…) … PrintWriter out = response.getWriter(); //use out to send content to the browser }}

HttpServletRequest and HttpServletResponse

• Servlets usually – not always – extend HttpServlet and override doGet and doPost methods of that class. Each takes two arguments, an HttpServletRequest and HttpServletResponse. Incoming data, like query string, headers and client hostname, is in the request. Status codes, respnse headers, and document content are sent back via the response.

Generating html

• Generally, most of your energy in generating a response is used in writing html via a printwriter.

packaging• If packages are used, servlets must be placed in subdirectories

matching the package name.• Package statement must appear first in the servlet code.• The lottery number generator servlet from chapter 3 has examples

of generating html and using a package. This servlet would need to be placed in a coreservlets subdirectory of classes, as in: C:\tomcat\webapps\ROOT\WEB-INF\classes\coreservlets

• The text recommends using an html validator to check the synatx of generated pages. WWW has one at http://validator.w3.org

• Text suggests cutting down page generation tedium by using utilities. Typically, if most of what you are doing is html generation, you would look elsewhere for your middle-tier solution, like at JSP.

Life cycle

• init() is called on servlet instantiation – put one-time setup code here.

• Afterwards, each user request causes a thread to be started which calls the service method of this servlet. If multiple calls occur, multiple threads are created, unless you have stipulated that the SingleThreadModel is to be used.

• Before termination, the server calls the servlet’s destroy method.

Service method

• Service method checks the request type (Get, Post, XXX) and calls doGet, doPost or doXXX appropriately. Get occurs from a URL page request or any HTML form with no method specified.

• Text advises not to override service method. Instead, if the servlet does the same thing for get and post and needs to provide both, doGet might be written and the doPost method simply calls doGet:

public void doPost(…)…{//just call doGetdoGet(…);}

More about init()

• Init typically initializes data that will be used throughout the life of the servlet. This might include time-consuming operations that only need to be done once.

• This might mean setting up a pool of db connections or a building a hashmap from a datafile.

• The lottery number example builds an array of numbers in init – these will remain the same until the server is shutdown or servlet is destroyed. It also stores the time in a variable modTime, in case a get request only wants the numbers if modified after a specified time.

Most of LotteryNumbers…see notes for entire servlet

package coreservlets;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class LotteryNumbers extends HttpServlet { private long modTime; private int[] numbers = new int[10]; public void init() throws ServletException { // Round to nearest second (i.e, 1000 milliseconds) modTime = System.currentTimeMillis()/1000*1000; for(int i=0; i<numbers.length; i++) { numbers[i] = randomNum(); } } /** Return the list of numbers that init computed. */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Your Lottery Numbers"; String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<B>Based upon extensive research of … best lottery numbers for you.</B>" + "<OL>"); for(int i=0; i<numbers.length; i++) { out.println(" <LI>" + numbers[i]); } out.println("</OL>" + "</BODY></HTML>"); }…}

Lottery Numbers

Initializations controlled by parameters

• Initialization parameters can also be used to set values when a servlet is loaded.

• These typically are used by deployers – they would enable the address of a database, the size of a connection pool or location of a file to be gleaned at startup from data in web.xml

• See Hunter chapter 3 notes for an example.

destroy()

• Use this to close db connections, write data to disk, close threads.

• Since the server may crash, do not rely on destroy being run.

SingleThreadModel

• Implementing this interface means you don’t have to worry about simultaneous access to instance variables, since only a single user (thread) can be executing at once, (or a pool of multiple instances).

• You do have to worry about access to static fields or shared data outside the servlet.

• SingleThreadModel hurts performance, and may not effectively synchronize access, so it should generally not be used. Instead synchronize sections of code where exclusion is needed.

Example – assign a unique user id.

• Hunter has examples illustrating this problem, too, so I don’t include a discussion of the problems here. The servlet is given and the “code fix” follows.

Generate unique user idspackage coreservlets;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;

public class UserIDs extends HttpServlet { private int nextID = 0; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Your ID"; String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<CENTER>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1>" + title + "</H1>\n"); String id = "User-ID-" + nextID;////notice not synched out.println("<H2>" + id + "</H2>"); nextID = nextID + 1; out.println("</BODY></HTML>"); }}

Properly synchronized

synchronized(this){

//an unnamed synch block

String id = "User-ID-" + nextID;

out.println("<H2>" + id + "</H2>");

nextID = nextID + 1;

}

UserIDs

debugging• Use print statements• Use an integrated debugger in the IDE. JBuilder, Eclipse and many IDEs let you

insert breakpoints, trace method calls, etc.• Use the log file. HTTPServlet class has a log method that lets you write to a file on

the server.• Use Log4J, part of the Apache project. It lets you insert debug statements and use an

XML config file to determine which are invoked at request time.• Write separate classes. As usual, decomposition and class cooperation can help

isolate if not eliminate errors.• Check for malformed or missing data.• Check the html source by using the browsers “view source” to find html errors.• L\Examine request data separately… The Core Servlets text provides an EchoServer

class to do this.• Look at the response separately. The WebClient class in Core Servlets text chapt 3

lets you connect ot the server, send HTTP data and view everything returned.• Stop and restart the server. If you change a lower-level class, even if your container

is set to reload your servlets when updated, maybe the change won’t be implemented.

WebClient

This is a standalone application (not a servlet!) that can be used to interactively connect to servers and test servlets, JSP pages, etc. Download all the files, compile it with "javac WebClient.java" (which will compile all the auxiliary files). Then, run it from the command line with "java WebClient", and type in the host, URI, HTTP headers, etc.

Running the Web Client