|
|
Servletsby Bill Venners Agenda
HTML Forms<FORM method="POST" action="subscribe.cgi"> <INPUT type=hidden name="userrequest" value="subsingle"> <INPUT type=hidden name="outputfile" value="suboutput"> <INPUT type=hidden name="errorfile" value="suberror"> <TABLE cols="3"> <TR> <TD align="right"> Your E-mail Address: </TD> <TD> <INPUT type="text" name="email"> </TD> <TD align="left"> <INPUT type="submit" value="Subscribe"> </TD> </TR> </TABLE> </FORM> GET and POST
CGI Programming
A CGI Script#!/usr/local/bin/perl
#
# Copyright (c) 1998 Bill Venners. All rights reserved.
#
$mailprogram = "/usr/lib/sendmail";
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
$outputtemplate = "$FORM{'outputfile'}.html";
$errortemplate = "$FORM{'errorfile'}.html";
$mailthis = "To: artima-request@lists.best.com\n";
# make sure the user entered a valid email address.
$temp = $FORM{'email'};
$temp =~ s/_/a/g;
$temp =~ s/-/a/g;
unless ($temp =~ /\w+@\w+\.\w\w+/) {
&error($FORM{'email'});
exit;
}
$mailthis .= "From: $FORM{'email'}\n";
$mailthis .= $FORM{'userrequest'};
open(MAIL,"|$mailprogram -t");
print MAIL "$mailthis\n";
close(MAIL);
&write_output_html($FORM{'email'});
exit;
sub write_output_html {
$email_address = $_[0];
open(OUTPUTTEMPLATE,"$outputtemplate") || die $!;
print "Content-type: text/html\n\n";
while ($line =
A Template File<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <HTML> <HEAD> <TITLE>Subscribe to the Artima Newsletter</TITLE> <META NAME="description" content="The Artima Newsletter is a monthly email publication announcing activities at artima.com, a resource for Java and Jini developers."> <META NAME="keywords" content="Java Newsletter, Mailing List"> <META NAME="author" content="Bill Venners"> </HEAD> <!--BEGIN_ARTIMA_COLOR_SCHEME--> <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000CC" VLINK="#660099" ALINK="000066"> <!--END_ARTIMA_COLOR_SCHEME--> <!--BEGIN_ARTIMA_LOGO--> <CENTER> <A href="index.html"> <IMG src="images/smartima.gif" alt="artima.com - a resource for Java and Jini developers" border="0" width="421" height="22"></A><BR> </CENTER> <!--END_ARTIMA_LOGO--> <!--BEGIN_LINKS--> <CENTER> <FONT size="-1" face="geneva, arial, sans-serif"> <A href="index.html">Artima</A> | <A href="search.html"><STRONG>Search</STRONG></A> | <A href="java/index.html">Java</A> | <A href="javadesign/index.html">Design</A> | <A href="jvm/index.html">JVM</A> | <A href="jini/index.html">Jini</A> | <A href="bookshop/index.html">Books</A> | <A href="javaseminars/index.html">Seminars</A> | <A href="subscribe.html"><STRONG>Subscribe</STRONG></A> </FONT> </CENTER> <BR> <!--END_LINKS--> <!--BEGIN_BURST:7:--> <CENTER> <A href="http://www.burstnet.com/ads/ad5150a-map.cgi/7" target=_top><IMG src="//www.burstnet.com/cgi-bin/ads/ad5150a.cgi/7" width=468 height=60 border=0></A> </CENTER> <BR> <!--END_BURST--> <!--BEGIN_TITLE_BLOCK--> <font face="arial, helvetica" COLOR="#000066"> <font size=6> <SPAN class=pagetitle1>Subscription Successful</SPAN> </font> </font> <!--END_TITLE_BLOCK--> <HR align="left" width="85%"> <TABLE CELLPADDING="3" CELLSPACING="0" BORDER="0" width="85%"> <TR> <TD width="100%" valign="top" rowspan="100"> <P> You have been successfully added to the Artima Newsletter's mailing list at the following e-mail address: <BLOCKQUOTE> <STRONG>?email_address?</STRONG> </BLOCKQUOTE> <P>You can expect a somewhat cryptic confirmation of your subscription via e-mail. The message will be from artima-errors@lists.best.com and the subject will be INFO RESPONSE. <P>If you change your mind, you can <A href="http://www.artima.com/unsubscribe.html">unsubscribe</A> at any time. <P> <HR align="left" width="100%"> Some entry points at <CODE>artima.com</CODE>: <BLOCKQUOTE> <UL> <LI><A href="http://www.artima.com/index.html">Artima Software</A> - the home page <LI><A href="http://www.artima.com/javaseminars/index.html">Java Seminars</A> - in-house and public classes taught by Biill Venners <LI><A href="http://www.artima.com/javabooks.html">Java Books</A> - books written or being written by Bill Venners <LI><A href="http://www.artima.com/bv/index.html">Bill Venners</A> - personal home page </UL> </BLOCKQUOTE> </TD> </TR> </TABLE> <HR width="100%"> <!--BEGIN_FOOTER--> <TABLE width="100%"> <TR> <TD align="left"> <FONT size="1" face="geneva, arial, sans-serif"> Last Updated: Wednesday, July 05, 2000 CGI With Servlets
Servlet Advantages
Other Advantages
A Basic Servlet 1 // In file Servlets/ex2/BasicServlet.java
2
3 import java.io.PrintWriter;
4 import java.io.IOException;
5 import javax.servlet.ServletException;
6 import javax.servlet.http.HttpServlet;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
9
10 public class BasicServlet extends HttpServlet {
11
12 public void doGet(HttpServletRequest request, HttpServletResponse response)
13 throws IOException, ServletException {
14
15 response.setContentType("text/html");
16
17 PrintWriter out = response.getWriter();
18 out.println("<HTML>");
19 out.println("<BODY>");
20 out.println("<HEAD>");
21 out.println("<TITLE>A Basic Servlet</TITLE>");
22 out.println("</HEAD>");
23 out.println("<BODY>");
24 out.println("<H1>A Basic Servlet</H1>");
25 out.println("<P>");
26 out.println("This page was produced by a servlet. Oh boy.");
27 out.println("</BODY>");
28 out.println("</HTML>");
29 }
30 }
Servlet Lifecycle
|
|
HTTP/1.1 200 OK Content-Type: text/plain Think Objects! |
PrintWriter isn't buffered
get/setBufferSize() and
isCommited() setStatus(int): standard waySC_NOT_FOUND, etc.)
sendError(int code, String msg): sends status code plus
HTML formatted msg
sendRedirect(String url): generates 302 response and
Location header with value url setHeader(String hdr, String val): sets header to value
setDateHeader(String hdr, long ms): sets header to
millisecs since epoch converted to date
setIntHeader(String hdr, int val): sets header to
val converted to string
setContentType(): sets Content-Type
setContentLength(): sets Content-Length
(for persistent connections)
addCookie(): inserts a cookie into
Set-Cookie
sendRedirect(String url): sets Location to
url plus status code to 302 getRequestProtocol() before using 1.1-only headers
Content-Encoding: compression technique
Content-Language: language of the data string
Content-Length: bytes of data being sent
Content-Type: MIME type
Last-Modified: when data was last changed
Pragma: no-cache for 1.0 clients
Set-Cookie: set a cookie Cache-Control Headerpublic: cacheable
private: for single user, cache only in private store
no-cache: never cache (same as Pragma:
no-cache)
no-store: don't cache or even make a temp file
must-revalidate: always go back to source
proxy-revalidate: shared caches must always go back to
source
max-age=xxx: consider stale after xxx
seconds
s-max-age=xxx: shared caches should consider data stale
after xxx seconds Refresh HeadersetIntHeader("Refresh", 60);
or setHeader("Refresh",
"5; http://www.artima.com/realindex.html");
HttpSession uses cookies, if supported, else
URL-rewriting
HttpSessionHttpSession session = request.getSession(true);
getAttribute(String name) - get a previously stored
Object value
setAttribute(String name, Object value) - associate a
value with a name
HttpSessionBindingListener,
valueBound() or valueUnbound() called
removeAttribute(String name) - removes any value
associated with name
getAttributeNames() - get names of all attributes for a
session
getID() - returns unique String key for
session
isNew() - true if just created
getCreationTime() - true if just created
getLastAccessTime() - returns time when client last
sent a request associated with the session
get/setMaxInactiveInterval() - get or set the number of
seconds after which a session should be automatically inactivated
invalidate() - true if just created
C:\jakarta-tomcat directory. For a users guide to tomcat,
visit C:\jakarta-tomcat\doc\uguide\tomcat_ug.html.
To configure the tomcat servlet container server, set the environment
variable TOMCAT_HOME to the installation directory, as in:
set TOMCAT_HOME=c:\jakarta-tomcat
To start tomcat, just run the startup batch file in the
bin subdirectory of the installation directory, as in:
c: cd \jakarta-tomcat startup
Once you've started the server, open a web browser and try connecting to your own port 8080, where tomcat will be running, by typing a URL into to browser's address field such as:
http://127.0.0.1:8080/
Click on Servlet Examples, then try to run the various example servlets on the Servlet Examples page.
FirstServlet.java that
just generates a web page with the greeting, "My first servlet works like
a charm!".
Compile your servlet, then move the FirstServlet.class
file to the webapps\examples\WEB-INF\classes subdirectory of
the tomcat installation directory.
Test your servlet by typing in its name into the browser's address field, using a URL such as:
http://taiping:8080/examples/servlet/FirstServlet
MyPages in
the webapps\examples directory of your tomcat installation
directory. In your MyPages directory, create a web page named
subscribe.html that allows a user to subscribe to your
mailing list. Place a form on the page that contains one text input field,
labeled "Your email address:". The
Create a servlet named SubscribeServlet.java, that just
generates a web page that prints out the value of the email address typed
into the form. Make sure your servlet will respond to both
GET and POST methods.
To run the servlet, once again just move the
SubscribeServlet.class file to the
webapps\examples\WEB-INF\classes subdirectory of the tomcat
installation directory, and type the appropriate URL into the browser's
address field, as in:
http://taiping:8080/examples/servlet/SubscribeServlet
Change the SubscribeServlet from Problem 3 so that it
verifies that a valid email address was typed in. An email address is
valid if it has one or more characters, a dot ('.'), one more characters,
the at sign ('@'), and one or more characters.
If the user types in a valid email address, just generate a web page
that says the user has successfully subscribed to your mailing list. If
the user does not provide a valid email address, generate an error page
that indicates they didn't type in a valid email address. On the error
page, include the an input field and submit button in which they can try
again. When they type in an email address on this error page and press
submit, they'll run your SubscribeServlet again.
Install and test your servlet, trying various valid and invalid email addresses.
SubscribeServlet called
SubscribeServlet2 that, instead of printing out hard coded
HTML tags from println() statements, reads in template files
that define the base HTML output for the success and error pages. The
servlet should search through the template file for a special trigger
character sequence, such as ?email_address?,
and replace that trigger with the actual email address typed into the
form.
Install and test your servlet with various valid and invalid email addresses.
CounterServlet
that just returns a web page that indicates how many times someone has
accessed that servlet. To do this, you'll need to create an instance
variable in the servlet that keeps track of how many accesses have already
occurred. Because incrementing an int or long is
not an atomic operation for a thread, you'll have to synchronize access to
that int or long counter variable.
Install and test your servlet. Each time you hit it, it should increment the number displayed back to the browser.
Create an ecommerce web application that allows a user to purchase
"Whiz-bang Widgets." Create one web page (titled "Buy a Whiz-Bang
Widgit!") that allows the user to specify his or her name and the number
of Whiz-bang Widgets desired. Make sure you say how much each widget will
cost. When the user submits this page, a servlet (named
WhizbangServlet.java) will verify that all fields have been
filled with valid responses. If not, the servlet should give an error page
that includes the same form (use a template file). If the user has typed
in valid data, the servlet should create a session object. The servlet
should store the user's name and desired widget count into the session
object, and return a page that has the title "Credit Card Information,"
that lists the total amount of widgets ordered, and the total price.
Install and test this form and servlet.
Enhance the Credit Card Information page from Problem 7, such that it contains a form that allows the user to type in his or her credit card information -- at a minimum: the credit card type (Visa, Mastercard, American Express, etc.), the credit card number, the name on the card, and the expiration date. To be nice, fill in the name on card field with the name the user typed into the name field of the previous (Buy a Whiz-Bang Widgit!) web page.
Create a new servlet, named CreditCardServlet.java, that
verifies that the form data typed into this page is valid. If not, show an
error page that includes the form so they can try again. If the user was
successful, add the credit card information to the session object and
print out a final verification page that contains all the information the
user has typed in. Ask the user if all this information is OK, and whether
or not he or she really wants all those Whizbang Widgets.
Create one final servlet, named SoldServlet.java, that
responds to the user pressing OK on the verification page returned by the
CreditCardServlet. This servlet should grab the session
object for the user and just print out a page that says, "Sold!", and
lists once again the user's name, the number of widgets, and the total
cost.