Chapter 5 Sending html information Aside on class

  • Slides: 66
Download presentation
Chapter 5 Sending html information

Chapter 5 Sending html information

Aside on class files for servlets • you already know you’ll need javax. servlet

Aside on class files for servlets • you already know you’ll need javax. servlet and javax. servlet. http • Here’s a link for a good site with javax/servlet and javax/servlet/http class files

https: //sdlc 1 e. sun. com/ECom. Action. Servlet

https: //sdlc 1 e. sun. com/ECom. Action. Servlet

Hello servlet public class Hello extends Http. Servlet { public void do. Get(Http. Servlet.

Hello servlet public class Hello extends Http. Servlet { public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); String name = req. get. Parameter("name"); out. println("<HTML>"); out. println("<HEAD><TITLE>Hello, " + name + "</TITLE></HEAD>"); out. println("<BODY>"); out. println("Hello, " + name); out. println("</BODY></HTML>"); } public String get. Servlet. Info() { return "A servlet that knows the name of the person to whom it's" + "saying hello"; }

A normal response • Recall that a status code indicates the result of the

A normal response • Recall that a status code indicates the result of the get method. • set. Content. Type() sets the content type of the response • get. Writer() returns a Print. Writer for writing char-based data • Latin-1 (ISO 8859 -1) is the charset used if none is specified. • It is a good idea to set the content type before you get a print writer. • Exceptions can be thrown (Illegal. State) if get. Output. Stream() has been called before set. Content. Type() and an Unsupported. Encoding if the char set is not known.

Binary data • Servlet. Output. Stream can be used to write binary data. You

Binary data • Servlet. Output. Stream can be used to write binary data. You can get a Servlet. Output. Stream using get. Output. Stream(). • But an Illegal. State. Exception is thrown if get. Writer() has already been called.

Persistent connections • Keep-alive connections can be used to optimize the return of content

Persistent connections • Keep-alive connections can be used to optimize the return of content to the client. • In a socket connection, a client makes a request, receives a response from the server, indicates it is finished by sending a blank line The server closes the socket.

Persistent connections • What if the page contains an <img> or <applet> tag? The

Persistent connections • What if the page contains an <img> or <applet> tag? The client will need a new connection. • A better approach would be to use the same socket for all information from this page. To do this, the client and server must agree on where/when the server’s response will end and the client’s next request will begin. • They could use a blank line for a token, but what if the response contained a blank line?

Persistent connections • Servers manage a content-length header for static files. • A servlet

Persistent connections • Servers manage a content-length header for static files. • A servlet can set content-length and gain the advantage of a persistent connection for dynamic content. • This method sets the length in bytes of the content being returned by the server. • This is an optional method. • Besides allowing the servlet to use a persistent connection, the client can accurately display progress towards completion of data transfer. • This method must be called before sending any of the content body, and the length must be exact.

Response buffering • A response buffer allows a servlet to write part of the

Response buffering • A response buffer allows a servlet to write part of the response with a guarantee that it won’t immediately be commited. If an error occurs, the servlet can go back and change headers and status code. (As long as the buffer hasn’t been flushed). • Buffering also allows servlet to avoid complicated content-length precalculations.

Buffering (pass in “important parameter”)

Buffering (pass in “important parameter”)

Running Buffering without important_parameter

Running Buffering without important_parameter

Buffering example: resets buffer and response, writes buffersize to log file Oct 1, 2006

Buffering example: resets buffer and response, writes buffersize to log file Oct 1, 2006 3: 57: 55 PM org. apache. catalina. core. Application. Context log INFO: Buffering: The default buffer size is 8192 Buffering writes in C: Program FilesTomcat 5. 5logslocalhost. today’sdate

Buffering source file import javax. servlet. *; import javax. servlet. http. *; import java.

Buffering source file import javax. servlet. *; import javax. servlet. http. *; import java. io. *; public class Buffering extends Http. Servlet { public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Buffer. Size(8 * 1024); // we set 8 K buffer here res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); int size = res. get. Buffer. Size(); // returns 8096 or greater // Record the default size, in the log("The default buffer size is " + size); out. println("The client won't see this"); reset(); //means response is reinitialized – ok if response not committed out. println("Nor will the client see this!"); reset(); out. println("And this won't be seen if send. Error() is called"); if (req. get. Parameter("important_parameter") == null) { res. send. Error(res. SC_BAD_REQUEST, "important_parameter needed"); } }}

Keep. Alive: request 16 k repsonse buffer

Keep. Alive: request 16 k repsonse buffer

Keep. Alive: note: It would not compile in jdk 1. 4 public void do.

Keep. Alive: note: It would not compile in jdk 1. 4 public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); // Ask for a 16 K byte response buffer; do not set the content length res. set. Buffer. Size(16 * 1024); //got error in jdk 1. 4 Print. Writer out = res. get. Writer(); out. println("<HTML>"); out. println("<HEAD><TITLE>Hello World</TITLE></HEAD>"); out. println("<BODY>"); out. println("<BIG>Less than 16 K of response body</BIG>"); out. println("</BODY></HTML>"); }

Keep. Alive – modified to ouptut its output buffer size

Keep. Alive – modified to ouptut its output buffer size

Keep. Alive import java. io. *; import javax. servlet. http. *; public class Keep.

Keep. Alive import java. io. *; import javax. servlet. http. *; public class Keep. Alive extends Http. Servlet { public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); // Ask for a 16 K byte response buffer; do not set the content length res. set. Buffer. Size(16 * 1024); int size = res. get. Buffer. Size(); // returns 8096 or greater Print. Writer out = res. get. Writer(); out. println("<HTML>"); out. println("<HEAD><TITLE>Hello World</TITLE></HEAD>"); out. println("<BODY>"); out. println("<BIG>The default buffer size is " + size+"</BIG>"); out. println("</BODY></HTML>"); } }

Controlling the response buffer • 1. 2. 5 methods to control response buffering: Servlet.

Controlling the response buffer • 1. 2. 5 methods to control response buffering: Servlet. Response. set. Buffer. Size(int bytect) tells server the minimum size buffer the servlet will need. The server may choose to provide an even larger buffer (to keep buffersizes fixed, for example). A large buffer allows more content to be written before any is sent. A smaller buffer decreases the load on memory and lets the client get response data more quickly. This method must be called before any response data is written. It will throw Illegal. State. Exception otherwise. Use Servlet. Response. get. Buffer. Size() to get the size of the buffer. It sends an int or 0 if no buffering is provided.

Controlling the response buffer 3. Use response. is. Committed() to determine if any response

Controlling the response buffer 3. Use response. is. Committed() to determine if any response has already been sent. If it returns true, it is too late to change headers and status codes. 4. Use response. reset() to start over with your response, clearing status codes and headers. It must be called before any response is commited. 5. send. Error() and send. Redirect() are discussed later. They clear the response buffer but do not change response headers.

Controlling the response buffer You can flush the response buffer (response. flush. Buffer()) to

Controlling the response buffer You can flush the response buffer (response. flush. Buffer()) to force content to be written to the client. This method automatically commits the response, meaning status code and headers are written and reset() can no longer be called. • The Buffering servlet uses the reset method.

Buffering (called by html form)

Buffering (called by html form)

Html form <FORM Method=GET Action="http: //localhost: 8080/myexamples/Buffer ing"> important parameter <input type=text name="important_parameter"><p> email

Html form <FORM Method=GET Action="http: //localhost: 8080/myexamples/Buffer ing"> important parameter <input type=text name="important_parameter"><p> email <input type=text name="email"><p> <input type=text name="comment"><p> <input type =submit> </form>

Buffering servlet: this needs jdk 1. 5

Buffering servlet: this needs jdk 1. 5

Buffering public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet.

Buffering public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Buffer. Size(8 * 1024); // 8 K buffer res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); int size = res. get. Buffer. Size(); // returns 8096 or greater…error in jdk 1. 4 // Record the default size, in the log("The default buffer size is " + size); out. println("The client won't see this"); reset(); //error in jdkj 1. 4 out. println("Nor will the client see this!"); reset(); out. println("And this won't be seen if send. Error() is called"); if (req. get. Parameter("important_parameter") == null) { res. send. Error(res. SC_BAD_REQUEST, "important_parameter needed"); } }

In the directory called logs find today’s log… Oct 10, 2005 12: 41: 11

In the directory called logs find today’s log… Oct 10, 2005 12: 41: 11 PM org. apache. catalina. core. Application. Context log INFO: Buffering: The default buffer size is 8192

Status codes • If a servlet doesn’t set the status code, the server will

Status codes • If a servlet doesn’t set the status code, the server will do it, setting it to a default 200=ok. • Using status codes allows a servlet to redirect a request or report a problem. • Table in text pg 137 lists status codes. • Response. set. Status(int code) allows a servlet to set the code.

View. File servlet import com. oreilly. servlet. Servlet. Utils; public class View. File extends

View. File servlet import com. oreilly. servlet. Servlet. Utils; public class View. File extends Http. Servlet { public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { // Use a Servlet. Output. Stream because we may pass binary information Servlet. Output. Stream out = res. get. Output. Stream(); // Get the file to view String file = req. get. Path. Translated(); // No file, nothing to view if (file == null) { out. println("No file to view"); return; } // Get and set the type of the file String content. Type = get. Servlet. Context(). get. Mime. Type(file); res. set. Content. Type(content. Type); // Return the file try { Servlet. Utils. return. File(file, out); } catch (File. Not. Found. Exception e) { out. println("File not found"); } catch (IOException e) { out. println("Problem sending file: " + e. get. Message()); } }

View. File modification try { Servlet. Utils. return. File(file, out); } catch (File. Not.

View. File modification try { Servlet. Utils. return. File(file, out); } catch (File. Not. Found. Exception e) { out. println("File not found"); } Without setting a status code, this is the best the servlet can do. Alternatively, it could use: try { Servlet. Utils. return. File(file, out); } catch (File. Not. Found. Exception e) { res. send. Error(res. SC_NOT_FOUND); }

View. File 2 sets an error code if file not found

View. File 2 sets an error code if file not found

Original View. File simply prints a message if file not found

Original View. File simply prints a message if file not found

View. File 2 sets error code

View. File 2 sets error code

send. Error • The result of send. Error is server dependent and typically is

send. Error • The result of send. Error is server dependent and typically is identical to the server’s own error page.

HTTP headers • Servlet can set and send an http header. • Table in

HTTP headers • Servlet can set and send an http header. • Table in text pg 141 lists response headers. • set. Header(String name, String value) • set. Date. Header(String name, long Date) • set. Int. Header(String name, int value) • contains. Header()

My. Site. Selector randomly selects a site

My. Site. Selector randomly selects a site

My. Site. Selector: reload

My. Site. Selector: reload

And again…

And again…

Site. Selector loads a randomly selected page and redirects

Site. Selector loads a randomly selected page and redirects

Site. Selector import java. io. *; import java. util. *; import javax. servlet. http.

Site. Selector import java. io. *; import java. util. *; import javax. servlet. http. *; public class Site. Selector extends Http. Servlet { Vector sites = new Vector(); Random random = new Random(); public void init() throws Servlet. Exception { sites. add. Element("http: //www. oreilly. com/catalog/jservlet"); sites. add. Element("http: //www. servlets. com"); sites. add. Element("http: //java. sun. com/products/servlet"); sites. add. Element("http: //www. new. Instance. com"); } public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); int site. Index = Math. abs(random. next. Int()) % sites. size(); String site = (String)sites. element. At(site. Index); res. set. Status(res. SC_MOVED_TEMPORARILY); res. set. Header("Location", site); }}

Go. To servlet: URL path entered after servlet info

Go. To servlet: URL path entered after servlet info

Sends you to that site

Sends you to that site

do. Get() method of Go. To servlet public void do. Get(Http. Servlet. Request req,

do. Get() method of Go. To servlet public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { // Determine the site where they want to go String site = req. get. Path. Info(); String query = req. get. Query. String(); // Handle a bad request if (site == null) { res. send. Error(res. SC_BAD_REQUEST, "Extra path info required"); } // Cut off the leading "/" and append the query string // We're assuming the path info URL is always absolute String url = site. substring(1) + (query == null ? "" : "? " + query); // Log the requested URL and redirect log(url); // or write to a special file res. send. Redirect(url); }

Client. Pull servlet • Client. Pull is similar to redirection, except browser displays first

Client. Pull servlet • Client. Pull is similar to redirection, except browser displays first page contents, then waits before going to next page. • In this example, the refresh header is specified on each retrieval.

Client. Pull servlet

Client. Pull servlet

Client. Pull screen, 10 seconds later

Client. Pull screen, 10 seconds later

Client. Pull do. Get() public void do. Get(Http. Servlet. Request req, Http. Servlet. Response

Client. Pull do. Get() public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); res. set. Header("Refresh", "10"); //every 10 seconds out. println(new Date(). to. String()); }

Primer. Searcher with refresh

Primer. Searcher with refresh

do. Get code res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer();

do. Get code res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); res. set. Header("Refresh", "10"); if (lastprime == 0) { out. println("Still searching for first prime. . . "); } else { out. println("The last prime discovered was " + lastprime); out. println(" at " + lastprime. Modified); }

Client. Pull. Move: relocates in 10 seconds

Client. Pull. Move: relocates in 10 seconds

Client. Pull. Move

Client. Pull. Move

Client. Pull. Move import java. util. *; import javax. servlet. http. *; public class

Client. Pull. Move import java. util. *; import javax. servlet. http. *; public class Client. Pull. Move extends Http. Servlet { static final String NEW_HOST = "http: //www. oreilly. com"; public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); String new. Location = NEW_HOST + req. get. Request. URI(); res. set. Header("Refresh", "10; URL=" + new. Location); //not likely valid out. println("The requested URI has been moved to a different host. <BR>"); out. println("Its new location is " + new. Location + "<BR>"); out. println("Your browser will take you there in 10 seconds. "); } }

Client. Pull refreshes every 10 seconds

Client. Pull refreshes every 10 seconds

Client. Pull • I slightly modified the textexample so that instead of simply refreshing

Client. Pull • I slightly modified the textexample so that instead of simply refreshing the time it adds the time onto a string and displays this string. At some point the string might get so long it throws an error.

Client. Pull import java. io. *; import java. util. *; import javax. servlet. http.

Client. Pull import java. io. *; import java. util. *; import javax. servlet. http. *; public class Client. Pull extends Http. Servlet { String long. String=""; public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); res. set. Header("Refresh", "10"); out. println(long. String=long. String+(new Date(). to. String()+'n')); } }

Rerouting to a new site

Rerouting to a new site

The new site…note URL

The new site…note URL

The servlet import java. io. *; import java. util. *; import javax. servlet. http.

The servlet import java. io. *; import java. util. *; import javax. servlet. http. *; public class My. Client. Pull. Move extends Http. Servlet { static final String NEW_HOST = "http: //employees. oneonta. edu/higgindm/"; public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); String new. Location = NEW_HOST + req. get. Request. URI(); res. set. Header("Refresh", "10; URL=" + new. Location+". html"); //might need to chop up URI and reassemble it out. println("The requested URI has been moved to a different host. <BR>"); out. println("Its new location is " + new. Location + "<BR>"); out. println("Your browser will take you there in 10 seconds. "); }}

Error. Display • This servlet could be used as a location reference to handle

Error. Display • This servlet could be used as a location reference to handle errors. • Could not figure out where to put the errorpage codes in my web. xml to get it to go to this servlet.

Error Handling: error page specification in web. xml • <location> specification does not need

Error Handling: error page specification in web. xml • <location> specification does not need to be a static page but can reference a JSP or servlet.

Error Handling: error page specification in web. xml <web-app> <!--…. > <error-page> <error-code> 400

Error Handling: error page specification in web. xml <web-app> <!--…. > <error-page> <error-code> 400 </error-code> <location> /page 400. html </location> </error-page> <error-code> 404 </error-code> <location> /Error. Display </location> </error-page> </web-app>

Error. Display import java. io. *; import javax. servlet. http. *; public class Error.

Error. Display import java. io. *; import javax. servlet. http. *; public class Error. Display extends Http. Servlet { public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); String code = null, message = null, type = null; Object exception. Obj, code. Obj, message. Obj, type. Obj; // Retrieve three possible error attributes, some may be null code. Obj = req. get. Attribute("javax. servlet. error. status_code"); message. Obj = req. get. Attribute("javax. servlet. error. message"); type. Obj = req. get. Attribute("javax. servlet. error. exception_type"); exception. Obj = req. get. Attribute("javax. servlet. error. exception"); //new in servlet 2. 3 // prev line was not in text example String exception=null; if (code. Obj != null) code = code. Obj. to. String(); if (message. Obj != null) message = message. Obj. to. String(); if (type. Obj != null) type = type. Obj. to. String(); if (exception. Obj != null) exception = exception. Obj. to. String(); else exception="no exception"; // The error reason is either the status code or exception type String reason = (code != null ? code : type);

Error. Display out. println("<HTML>"); out. println("<HEAD><TITLE>" + reason + ": " + message +

Error. Display out. println("<HTML>"); out. println("<HEAD><TITLE>" + reason + ": " + message + exception + "</TITLE></HEAD>"); out. println("<BODY>"); out. println("<H 1>" + "reason: " + reason + "</H 1>"); out. println("<H 2>" + "message: " + message+ "</H 2>"); out. println("<H 2>" + "exception: " +exception +"</H 2>"); out. println("<HR>"); out. println("<I>Error accessing " + req. get. Request. URI() + "</I>"); out. println("</BODY></HTML>"); }

Error. Display

Error. Display

Error Handling remarks • set. Status() allows you to set an error code and

Error Handling remarks • set. Status() allows you to set an error code and continue processing/handling the response. • send. Error() lets you set a code a then passes control to the server for page handling. • An <error-page> rule in web. xml will let you tell the server to send a special page.

File. Location

File. Location

File. Location. java (Not sure where it is finding the file) import java. io.

File. Location. java (Not sure where it is finding the file) import java. io. *; import java. util. *; import javax. servlet. http. *; public class File. Location extends Http. Servlet { public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); if (req. get. Path. Info() != null) { out. println("The file "" + req. get. Path. Info() + """); out. println("Is stored at "" + req. get. Path. Translated() + """); } else { out. println("Path info is null, no file to lookup"); } }}