Title: Sending html information
1Chapter 5
2Aside on class files for servlets
- you already know youll need javax.servlet and
javax.servlet.http - Heres a link for a good site with javax/servlet
and javax/servlet/http class files
3https//sdlc1e.sun.com/ECom/EComActionServlet
4Hello servlet
- public class Hello extends HttpServlet
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/html")
- PrintWriter out res.getWriter()
- String name req.getParameter("name")
- out.println("ltHTMLgt")
- out.println("ltHEADgtltTITLEgtHello, " name
"lt/TITLEgtlt/HEADgt") - out.println("ltBODYgt")
- out.println("Hello, " name)
- out.println("lt/BODYgtlt/HTMLgt")
-
- public String getServletInfo()
- return "A servlet that knows the name of the
person to whom it's" - "saying hello"
5A normal response
- Recall that a status code indicates the result of
the get method. - setContentType() sets the content type of the
response - getWriter() returns a PrintWriter 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 (IllegalState) if
getOutputStream() has been called before
setContentType() and an UnsupportedEncoding if
the char set is not known.
6Binary data
- ServletOutputStream can be used to write binary
data. You can get a ServletOutputStream using
getOutputStream(). - But an IllegalStateException is thrown if
getWriter() has already been called.
7Persistent 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.
8Persistent connections
- What if the page contains an ltimggt or ltappletgt
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 servers response will end and the clients
next request will begin. - They could use a blank line for a token, but what
if the response contained a blank line?
9Persistent 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.
10Response buffering
- A response buffer allows a servlet to write part
of the response with a guarantee that it wont
immediately be commited. If an error occurs, the
servlet can go back and change headers and status
code. (As long as the buffer hasnt been
flushed). - Buffering also allows servlet to avoid
complicated content-length pre-calculations.
11Buffering (pass in important parameter)
12Running Buffering without important_parameter
13Buffering example resets buffer and response,
writes buffersize to log file
- Oct 1, 2006 35755 PM org.apache.catalina.core.Ap
plicationContext log - INFO Buffering The default buffer size is 8192
- Buffering writes in C\Program Files\Tomcat
5.5\logs\localhost.todaysdate
14Buffering source file
- import javax.servlet.
- import javax.servlet.http.
- import java.io.
- public class Buffering extends HttpServlet
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setBufferSize(8 1024) // we set 8K
buffer here - res.setContentType("text/html")
- PrintWriter out res.getWriter()
- int size res.getBufferSize() // returns
8096 or greater - // Record the default size, in the log
- log("The default buffer size is " size)
- out.println("The client won't see this")
- res.reset()//means response is reinitialized
ok if response not committed - out.println("Nor will the client see this!")
- res.reset()
- out.println("And this won't be seen if
sendError() is called") - if (req.getParameter("important_parameter")
null) - res.sendError(res.SC_BAD_REQUEST,
"important_parameter needed")
15KeepAlive request 16k repsonse buffer
16KeepAlive note It would not compile in jdk1.4
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/html")
- // Ask for a 16K byte response buffer do not
set the content length - res.setBufferSize(16 1024)//got error in
jdk1.4 - PrintWriter out res.getWriter()
- out.println("ltHTMLgt")
- out.println("ltHEADgtltTITLEgtHello
Worldlt/TITLEgtlt/HEADgt") - out.println("ltBODYgt")
- out.println("ltBIGgtLess than 16K of response
bodylt/BIGgt") - out.println("lt/BODYgtlt/HTMLgt")
-
17KeepAlive modified to ouptut its output buffer
size
18KeepAlive
- import java.io.
- import javax.servlet.
- import javax.servlet.http.
- public class KeepAlive extends HttpServlet
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/html")
- // Ask for a 16K byte response buffer do not
set the content length - res.setBufferSize(16 1024)
- int size res.getBufferSize() // returns
8096 or greater - PrintWriter out res.getWriter()
- out.println("ltHTMLgt")
- out.println("ltHEADgtltTITLEgtHello
Worldlt/TITLEgtlt/HEADgt") - out.println("ltBODYgt")
- out.println("ltBIGgtThe default buffer size is
" size"lt/BIGgt") - out.println("lt/BODYgtlt/HTMLgt")
-
-
19Controlling the response buffer
- 5 methods to control response buffering
- ServletResponse.setBufferSize(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 IllegalStateException otherwise. - Use ServletResponse.getBufferSize() to get the
size of the buffer. It sends an int or 0 if no
buffering is provided.
20Controlling the response buffer
- 3. Use response.isCommitted() to determine if
any response has already been sent. If it returns
true, it is too late to change headers and status
codes. - Use response.reset() to start over with your
response, clearing status codes and headers. It
must be called before any response is commited. - sendError() and sendRedirect() are discussed
later. They clear the response buffer but do not
change response headers.
21Controlling the response buffer
- You can flush the response buffer
(response.flushBuffer()) 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.
22Buffering (called by html form)
23Html form
- ltFORM MethodGET Action"http//localhost8080/mye
xamples/Buffering"gt - important parameter ltinput typetext
name"important_parameter"gtltpgt - email ltinput typetext name"email"gtltpgt
- ltinput typetext name"comment"gtltpgt
- ltinput type submitgt
- lt/formgt
24Buffering servlet this needs jdk1.5
25Buffering
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setBufferSize(8 1024) // 8K buffer
- res.setContentType("text/html")
- PrintWriter out res.getWriter()
- int size res.getBufferSize() // returns
8096 or greatererror in jdk1.4 - // Record the default size, in the log
- log("The default buffer size is " size)
- out.println("The client won't see this")
- res.reset()//error in jdkj1.4
- out.println("Nor will the client see this!")
- res.reset()
- out.println("And this won't be seen if
sendError() is called") - if (req.getParameter("important_parameter")
null) - res.sendError(res.SC_BAD_REQUEST,
"important_parameter needed") -
26In the directory called logs find todays log
- Oct 10, 2005 124111 PM org.apache.catalina.core.
ApplicationContext log - INFO Buffering The default buffer size is 8192
27Status codes
- If a servlet doesnt set the status code, the
server will do it, setting it to a default
200ok. - Using status codes allows a servlet to redirect a
request or report a problem. - Table in text pg 137 lists status codes.
- Response.setStatus(int code) allows a servlet to
set the code.
28ViewFile servlet
- import com.oreilly.servlet.ServletUtils
- public class ViewFile extends HttpServlet
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - // Use a ServletOutputStream because we may
pass binary information - ServletOutputStream out res.getOutputStream(
) - // Get the file to view
- String file req.getPathTranslated()
- // No file, nothing to view
- if (file null)
- out.println("No file to view")
- return
- // Get and set the type of the file
- String contentType getServletContext().getMi
meType(file) - res.setContentType(contentType)
- // Return the file
- try
- ServletUtils.returnFile(file, out)
- catch (FileNotFoundException e)
29ViewFile modification
- try
- ServletUtils.returnFile(file, out)
-
- catch (FileNotFoundException e)
- out.println("File not found")
-
- Without setting a status code, this is the best
the servlet can do. Alternatively, it could use - try
- ServletUtils.returnFile(file, out)
-
- catch (FileNotFoundException e)
- res.sendError(res.SC_NOT_FOUND)
-
30ViewFile2 sets an error code if file not found
31Original ViewFile simply prints a message if file
not found
32ViewFile2 sets error code
33sendError
- The result of sendError is server dependent and
typically is identical to the servers own error
page.
34HTTP headers
- Servlet can set and send an http header.
- Table in text pg 141 lists response headers.
- setHeader(String name,String value)
- setDateHeader(String name,long Date)
- setIntHeader(String name,int value)
- containsHeader()
35MySiteSelector randomly selects a site
36MySiteSelector reload
37And again
38SiteSelector loads a randomly selected page and
redirects
39SiteSelector
- import java.io.
- import java.util.
- import javax.servlet.
- import javax.servlet.http.
- public class SiteSelector extends HttpServlet
- Vector sites new Vector()
- Random random new Random()
- public void init() throws ServletException
- sites.addElement("http//www.oreilly.com/catal
og/jservlet") - sites.addElement("http//www.servlets.com")
- sites.addElement("http//java.sun.com/products
/servlet") - sites.addElement("http//www.newInstance.com")
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/html")
- PrintWriter out res.getWriter()
- int siteIndex Math.abs(random.nextInt())
sites.size() - String site (String)sites.elementAt(siteInde
x) - res.setStatus(res.SC_MOVED_TEMPORARILY)
40GoTo servlet URL path entered after servlet info
41Sends you to that site
42doGet() method of GoTo servlet
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - // Determine the site where they want to go
- String site req.getPathInfo()
- String query req.getQueryString()
- // Handle a bad request
- if (site null)
- res.sendError(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.sendRedirect(url)
-
43ClientPull servlet
- ClientPull 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.
44ClientPull servlet
45ClientPull screen, 10 seconds later
46ClientPull doGet()
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/plain")
- PrintWriter out res.getWriter()
- res.setHeader("Refresh", "10")//every 10
seconds - out.println(new Date().toString())
-
47PrimerSearcher with refresh
48doGet code
- res.setContentType("text/plain")
- PrintWriter out res.getWriter()
- res.setHeader("Refresh","10")
- if (lastprime 0)
- out.println("Still searching for first
prime...") -
- else
- out.println("The last prime discovered was
" lastprime) - out.println(" at " lastprimeModified)
-
49ClientPullMove relocates in 10 seconds
50ClientPullMove
51ClientPullMove
- import java.util.
- import javax.servlet.
- import javax.servlet.http.
- public class ClientPullMove extends HttpServlet
- static final String NEW_HOST
"http//www.oreilly.com" - public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/html")
- PrintWriter out res.getWriter()
- String newLocation NEW_HOST
req.getRequestURI() - res.setHeader("Refresh", "10 URL"
newLocation)//not likely valid - out.println("The requested URI has been moved
to a different host.ltBRgt") - out.println("Its new location is "
newLocation "ltBRgt") - out.println("Your browser will take you there
in 10 seconds.") -
-
52ClientPull refreshes every 10 seconds
53ClientPull
- 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.
54ClientPull
- import java.io.
- import java.util.
- import javax.servlet.
- import javax.servlet.http.
- public class ClientPull extends HttpServlet
- String longString""
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/plain")
- PrintWriter out res.getWriter()
- res.setHeader("Refresh", "10")
- out.println(longStringlongString(new
Date().toString()'\n')) -
-
55Rerouting to a new site
56The new sitenote URL
57The servlet
- import java.io.
- import java.util.
- import javax.servlet.
- import javax.servlet.http.
- public class MyClientPullMove extends HttpServlet
- static final String NEW_HOST
"http//employees.oneonta.edu/higgindm/" - public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/html")
- PrintWriter out res.getWriter()
- String newLocation NEW_HOST
req.getRequestURI() - res.setHeader("Refresh", "10 URL"
newLocation".html") - //might need to chop up URI and reassemble it
- out.println("The requested URI has been moved
to a different host.ltBRgt") - out.println("Its new location is "
newLocation "ltBRgt") - out.println("Your browser will take you there
in 10 seconds.")
58ErrorDisplay
- This servlet could be used as a location
reference to handle errors. - Could not figure out where to put the error-page
codes in my web.xml to get it to go to this
servlet.
59Error Handling error page specification in
web.xml
- ltlocationgt specification does not need to be a
static page but can reference a JSP or servlet.
60Error Handling error page specification in
web.xml
- ltweb-appgt
- lt!--.gt
- lterror-pagegt
- lterror-codegt
- 400
- lt/error-codegt
- ltlocationgt
- /page400.html
- lt/locationgt
- lt/error-pagegt
- lterror-pagegt
- lterror-codegt
- 404
- lt/error-codegt
- ltlocationgt
- /ErrorDisplay
- lt/locationgt
- lt/error-pagegt
- lt/web-appgt
61ErrorDisplay
- import java.io.
- import javax.servlet.
- import javax.servlet.http.
- public class ErrorDisplay extends HttpServlet
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/html")
- PrintWriter out res.getWriter()
- String code null, message null, type
null - Object exceptionObj, codeObj, messageObj,
typeObj - // Retrieve the three possible error
attributes, some may be null - codeObj req.getAttribute("javax.servlet.e
rror.status_code") - messageObj req.getAttribute("javax.servlet.e
rror.message") - typeObj req.getAttribute("javax.servlet.erro
r.exception_type") - exceptionObj req.getAttribute("javax.servlet
.error.exception")//new in servlet 2.3 - // prev line was not in text example
- String exceptionnull
- if (codeObj ! null) code
codeObj.toString() - if (messageObj ! null) message
messageObj.toString()
62ErrorDisplay
- out.println("ltHTMLgt")
- out.println("ltHEADgtltTITLEgt" reason " "
message exception "lt/TITLEgtlt/HEADgt") - out.println("ltBODYgt")
- out.println("ltH1gt" "reason" reason
"lt/H1gt") - out.println("ltH2gt" "message" message
"lt/H2gt") - out.println("ltH2gt" "exception" exception
"lt/H2gt") - out.println("ltHRgt")
- out.println("ltIgtError accessing "
req.getRequestURI() "lt/Igt") - out.println("lt/BODYgtlt/HTMLgt")
-
63ErrorDisplay
64Error Handling remarks
- setStatus() allows you to set an error code and
continue processing/handling the response. - sendError() lets you set a code a then passes
control to the server for page handling. - An lterror-pagegt rule in web.xml will let you tell
the server to send a special page.
65FileLocation
66FileLocation.java(Not sure where it is finding
the file)
- import java.io.
- import java.util.
- import javax.servlet.
- import javax.servlet.http.
- public class FileLocation extends HttpServlet
- public void doGet(HttpServletRequest req,
HttpServletResponse res) - throws
ServletException, IOException - res.setContentType("text/plain")
- PrintWriter out res.getWriter()
- if (req.getPathInfo() ! null)
- out.println("The file \""
req.getPathInfo() "\"") - out.println("Is stored at \""
req.getPathTranslated() "\"") -
- else out.println("Path info is null,
no file to lookup") -