Professional Documents
Culture Documents
FAQ
Compiled by
Srinivas Satya
Infosys Internet Consulting Practice
# 27, Bannerghatta Road,
Bangalore 76
India
TABLE OF CONTENTS
How does the performance of JSP pages compare with that of servlets? How does it compare
with Perl scripts?_______________________________________________________________3
What's a better approach for enabling thread-safe servlets and JSPs? SingleThreadModel
Interface or Synchronization?____________________________________________________4
How can I further optimize my servlets?____________________________________________5
How do I set my CLASSPATH for servlets?__________________________________________5
Why doesn't my servlet work inside a <SERVLET> tag?_______________________________6
How do I fully shut down the server?_______________________________________________6
My browser says "the server returned an invalid or unrecognized response" -- what gives?___7
What is the HelloWorld Servlet?___________________________________________________7
How do I get the name of the currently executing script?_______________________________7
How do I mix JSP and SSI #include?______________________________________________8
How do I ensure that my servlet is thread-safe?______________________________________8
How do I use Session Tracking?__________________________________________________10
How can I detect whether the user accepted my cookie?_______________________________10
How do I integrate HTML design into my Servlet?___________________________________11
How do I send email from a servlet?______________________________________________13
Are there any ISPs that will host my servlets?_______________________________________13
What is the difference between URL encoding and URL rewriting?_____________________13
How can my applet communicate with my servlet?___________________________________14
How can I debug my servlet?____________________________________________________15
How do I create an image (GIF, JPEG, etc.) on the fly from a servlet?___________________17
How do I upload a file to my servlet?______________________________________________18
How do I access a database from my servlet?_______________________________________19
Produ
ct
Tomcat
JSWDK
JSDK
JSDK
Versio
n
3.0
1.0.1
2.1
2.0
Servlet
spec
2.2
2.1
2.1
2.0
JSP
spec
1.1
1.0.1
none
none
Other servlet engines have their own conventions. Usually on the file
system it's "servlets" and in a URL it's "/servlet" (which is an alias or
virtual path). ]
Why doesn't my servlet work inside a <SERVLET> tag?
If you use your servlet inside an SSI, you must use
res.getOutputStream() and not res.getWriter(). Check the server error
logs for more details.
How do I support both GET and POST protocol from the same
Servlet?
The easy way is, just support POST, then have your doGet method call
your doPost method:
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
doPost(req, res);
}
Note that implementing the service() method is usually not what you
want to do, since HttpServlet provides its own implementation of
service() that turns around and calls doGet(), doPost(), etc.
Lee Crocker (LCrocker@INFORMANT.COM): "It's probably cleaner not
to override service() when extending HttpServlet. The existing service
method just calls doGet(), doPost(), etc. as appropriate, so you can
certainly override it if you feel like it, but then you wind up not only
treating GET and POST identically, but also all other HTTP commands,
like HEAD, TRACE, and OPTIONS. If you want GET and POST to do the
same thing, just have doGet() and doPost() call the same private
method that does all the work."
How do I fully shut down the server?
For JWS, under Windows, pressing control-C doesn't fully shut down
the server. You should use the Admin Tool and click "Shut Down". (Or
you can hit ctl-alt-del, find "JREW" in the list, and "End Task".)
My browser says "the server returned an invalid or unrecognized
response" -- what gives?
This is probably due to a NullPointerException being thrown. There's a
bug in JWS 1.1 whereby it doesn't correctly log these exceptions.
The solution is to put your doPost() method inside a try block and
catch NullPointerException. See the debugging question in this FAQ
for more details and source code.
What is the HelloWorld Servlet?
public class HelloHttpServlet extends HttpServlet
{
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException
{
String name = req.getParameter("name");
if (name == null) name = "Joe";
res.setContentType("text/plain");
ServletOutputStream out = res.getOutputStream();
out.println("Hello, " + name + "!");
}
}
http://www.purpletech.com/servlets/HelloEcho/extra/info?
height=100&width=200
getReques
/servlets/HelloEcho/extra/info
tURI
getServlet
/servlets/HelloEcho
Path
getPathInf
/extra/info
o
getQueryS
height=100&width=200
tring
This is useful if your form is self-referential; that is, it generates a
form which calls itself again. For example:
out.println("<FORM METHOD=POST ACTION=\"" +
res.encodeURL(req.getServletPath()) +
"\">");
out.println("<INPUT NAME=value>");
out.println("<INPUT TYPE=submit>");
out.println("</FORM>");
(encodeURL adds session information if necessary. See the Sun Servlet
Tutorial and this FAQ's Session Tracking question. Note that this
method was renamed from "encodeUrl" to the properly-capitalized
"encodeURL" somewhere around version 2.1 of the servlet spec.)
Note that early versions of Java Web Server and some servlet engines
had a bug whereby getRequestURI would also return the GET
parameters following the extra path info.
How do I mix JSP and SSI #include?
If you're just including raw HTML, use the #include directive as usual
inside your .jsp file.
<!--#include file="data.inc"-->
But it's a little trickier if you want the server to evaluate any JSP code
that's
inside
the
included
file.
Ronel
Sumibcay
(ronel@LIVESOFTWARE.COM) says: If your data.inc file contains jsp
code you will have to use
<%@ vinclude="data.inc" %>
The <!--#include file="data.inc"--> is used for including non-JSP files.
How do I ensure that my servlet is thread-safe?
This is actually a very complex issue. A few guidelines:
1. The init() method is guaranteed to be called once per servlet
instance, when the servlet is loaded. You don't have to worry
about thread safety inside this method, since it is only called by
a single thread, and the web server will wait until that thread
exits before sending any more threads into your service()
method.
2. Every new client request generates a new thread; that thread
calls the service() method of your servlet (which may in turn call
doPost(), doGet() and so forth).
3. Under most circumstances, there is only one instance of your
servlet, no matter how many client requests are in process. That
means that at any given moment, there may be many threads
running inside the service() method of your solo instance, all
sharing the same instance data and potentially stepping on each
other's toes. This means that you should be careful to
synchronize access to shared data (instance variables) using
the synchronized keyword.
4. Note that you need not (and should not) synchronize on local
data or parameters. And especially you shouldn't synchronize the
service() method! (Or doPost(), doGet() et al.)
5. A simple solution to synchronizing is to always synchronize on
the servlet instance itself using "synchronized (this) { ... }".
However, this can lead to performance bottlenecks; you're
usually better off synchronizing on the data objects themselves.
The question can be rephrased, "How can I design a work flow that
incorporates HTML designers and programmers to build a dynamically
generated web site that will keep expanding and growing over time?"
This is a special case of the intractable Content Management Problem
of the Web in general. The real problem is to allow HTML designers
(that is, humans) to use their favorite HTML editing tools without
learning Java, and to allow marketing people (arguably humans) to
change the look of the site on a whim, without having to alter the
database access code inside the servlet. (And vice versa -- to alter the
business logic and data access without altering the user interface.)
See
my
article
at
Servlet
Central
(http://www.servletcentral.com/1998-12/designprocess.dchtml) for an
expansion on these themes.
There are many, many possibilities... The list below is not complete,
but should give you some guidelines.
A. Hardcode HTML. You can just put HTML inside of print statements
in your Servlet's doGet() or doPost() method.
Pro: easy to code, easy to understand for the programmer.
Con: difficult to understand for the designer; when a change has to be
made, the programmer has to wait for the designer to finish her HTML,
then re-hard-code it all back into print statements, then make sure the
generated HTML actually does what the original HTML did. Basically,
good for a hello world servlet, not good for a real web site.
B. Server Side Includes (SSI). Use the <SERVLET> tag inside your
HTML file (and rename it .shtml). The HTML designers will make pretty
pages; your servlets will output small pieces of text that get spliced in
to the web page by the server.
Pro: separates UI (HTML) and code.
Con: You have two possible end paths with SSI: either your servlet
outputs many tiny bits of text with no HTML tags, or your servlet
outputs a big bunch of text with embedded HTML tags. In the first
case, your code can't take advantage of its knowledge of the structure
of the data -- for example, you can't format an HTML table from a
database. In the second case, you're back to hardcoding HTML, thus
making it hard to change the look of your pages.
C. Presentation Templates. This is a good way to put common
navigation elements (button bar, credits, etc) on all of your pages. The
technology is built in to the Java Web Server, and implemented by
several (though not all) of the servlet engines.
Pro: you don't have to enter in the same common HTML for all the
This sort of system is very difficult to design and build, but once you've
built it, it can really pay off -- but only if you have dozens of writers,
editors, designers, and programmers all working on the same site on
an ongoing basis.
For a brief list of alternate page template systems, see the References
section of this FAQ.
How do I send email from a servlet?
From: James Cooper (pixel@bitmechanic.com) GSP and GnuJSP both
come with SMTP classes that make sending email very simple. if you
are writing your own servlet you could grab one of the many SMTP
implementations from www.gamelan.com (search for SMTP and java).
All the ones I've seen are pretty much the same -- open a socket on
port 25 and drop the mail off. so you have to have a mail server
running that will accept mail from the machine JServ is running on.
See also the references section for a good list of Java email resources,
including SMTP and POP classes.
Are there any ISPs that will host my servlets?
The Adrenaline Group maintains a list of ISP's who host Java Servlets
(http://www.adrenalinegroup.com/jwsisp.html) . Of these, a few have
also said that they can host Java applications:
Centralogic (http://www.centralogic.com/)
Electronaut (http://www.electronaut.com/)
(or
There's also a feature of the Apache web server called URL Rewriting;
it is enabled by the mod_rewrite module. It rewrites URLs on their way
in to the server, allowing you to do things like automatically add a
trailing slash to a directory name, or to map old file names to new file
names. This has nothing to do with servlets. For more information, see
the Apache FAQ (http://www.apache.org/docs/misc/FAQ.html#rewritemore-config) .
How can my applet communicate with my servlet?
It's pretty straightforward. You can use the java.net.URLConnection
and java.net.URL classes to open a standard HTTP connection to the
web server. The server then passes this information to the servlet in
the normal way. Basically, the applet pretends to be a web browser,
and the servlet doesn't know the difference. (Of course, you can write
a servlet that is only called from your applet, in which case it *does*
know the difference...)
For more detail, you can see the Sun Web Server FAQ
(http://www.sun.com/software/jwebserver/faq/faq.html) Questions C8
(http://www.sun.com/software/jwebserver/faq/faq.html#c8) and C9
(http://www.sun.com/software/jwebserver/faq/faq.html#c9) . Also,
Chad Darby has an article with source code (http://www.j-
nine.com/pubs/applet2servlet/index.htm)
on
the
subject.
And
Netscape DevEdge Online has a similar article - Applet-to-Servlet
Communication
for
Enterprise
Applications
(http://developer.netscape.com/viewsource/index_frame.html?
content=fields_servlet/fields_servlet.html) skip to the "Communication
Tactics" section to get to the good part.
How can I debug my servlet?
Hoo boy, that's a tough one.
First off, you should always do your own exception handling. An
uncaught exception can silently kill your servlet, and if you don't know
where to look in the log files, or if your server has a bug in it whereby
it silently swallows certain exceptions, you'll have no idea where the
trouble is.
The following code sets up a catch block that will trap any exception,
and print its value to standard error output and to the
ServletOutputStream so that the exception shows up on the browser
(rather than being swallowed by the log file). Chances are that any
error is in your code; the exception shows you what line the problem
happened at. (If you see "Compiled Code" instead of line numbers in
the exception stack trace, then turn off the JIT in your server.)
res.setContentType("text/html");
ServletOutputStream out = res.getOutputStream();
try {
// do your thing here
...
}
catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
out.println("<pre>");
out.print(sw.toString());
out.println("</pre>");
}
Lately, I've started catching all Throwables, just in case. I know this is
bad form but what are you gonna do?
Next, you should make liberal use of the log() method, and you should
keep your own log files. Again, don't trust the server to do the right
thing. Also, printing the log after every request can help debugging
because you can immediately see the output of your servlet without
going into the server-side log files. (Another problem this avoids is
that some servlet engines forget to flush their logs after each request,
so even if you go to the server, you won't see the most recent log
messages.)
Here's some source code you can add to any HttpServlet that keeps an
in-memory log:
StringBuffer logBuffer = new StringBuffer();
public void log(String s) {
s = new Date().toString() + ": " + s;
System.err.println(s);
logBuffer.append(s);
logBuffer.append("\n");
super.log(s);
}
And here's some code that you can add to the end of your doGet or
doPost method that prints out the entire log after each request:
out.println("<HR>\n<H3>Error log this session:</H3>\n<PRE>");
out.println(logBuffer.toString());
out.println("</PRE><P>");
Both of these should be disabled once you actually ship your servlet,
but they can be very useful during development and debugging.
You should remember to use servletrunner (renamed "JSDK
WebServer" with the JSDK version 2 -- run with the script startserver)
to debug your servlet. It's a tool that ships with the JSDK that basically
starts up a miniature web server that runs your servlet inside itself. It
means you don't have to stop and restart your real web server every
time you recompile your servlet. It also affords a more pure
environment, so you can make sure your servlet truly conforms to the
spec before you try to run it inside a (possibly buggy or nonstandard)
servlet engine.
A few IDEs support servlet debugging. Symantec Cafe claims to have a
fairly robust system for doing visual source-level debugging of servlets
(as well as RMI, CORBA, and EJB objects). [If anyone has any
experience with Cafe or other IDEs, please email &feedback;.] May
Wone (abc408@hotmail.com) writes:
I am debugging servlets running servletRunner inside of IBM's
VisualAge for Java.
at:
jRun also claims to have excellent log file support as well as some
debugging facilities.
Eric Gilbertson (eric@bitsource.com) adds:
Another way to debug servlets is to invoke JWS with java_g and
then attach to the process using any debugger that is capable of
attaching to a running Java process given a debug password. To
do this invoke JWS as follows:
java_g.exe -debug -Dserver.name="javawebserver" [extra
args...] com.sun.server.ServerProcess
jdb password=[password]
This will start the Web server process and echo a password. The
password may be then used with jdb to attach to the process.
Note that this will start only the Web server, not the admin
server.
Sun does not advertise this mechanism which in my mind is the
only way to debug non-trivial servlets.
How do I create an image (GIF, JPEG, etc.) on the fly from a servlet?
To create an image or do image processing from Java, there are
several packages and classes available. See the References section for
a list.
Once you have an image file in your servlet, you have two choices:
1. Write the file to disk and provide a link to it. Make sure you
write it to a location that's in your web server directory tree (not
just anywhere on the server's disk). (Note that in some servlet
Other uses (e.g. storing the file as a binary object in a database) will
require adaptation.
There is a multipart/form parser availailable from Anders Kristensen
(http://www-uk.hpl.hp.com/people/ak/java/, ak@hplb.hpl.hp.com) at
http://www-uk.hpl.hp.com/people/ak/java/#utils. JavaMail also has
MIME-parsing routines (see the References section).
Here is an example of HTML code that allows file upload, courtesy of
Detlef Pleiss (dpleiss@os-net.de):
<FORM ENCTYPE="multipart/form-data" method=post
action="..."> put the servlet URL here, of course
<INPUT
TYPE="file"
NAME="mptest"><INPUT
TYPE="submit"
VALUE="upload">
</FORM>
The input type "file" brings up a button for a file select box on the
browser together with a text field that takes the file name once
selected. The servlet uses the GET method parameters to decide what
to do with the upload while the POST body of the request contains the
file data to parse. Tested with IE4, IE5 and Netscape 4.5.
How do I access a database from my servlet?
Since JDK 1.1, Java comes with a package called JDBC (Java Database
Connectivity). JDBC allows you to write SQL queries as Java Strings,
pass them to the database, and get back results that you can parse. To
learn how to write JDBC code, check the tutorials on Sun's web site,
and read the Javadoc API documentation for package java.sql. To
install JDBC on your system, you need to locate a JDBC Driver for
your particular database and put it in your classpath. Fortunately, most
databases these days ship with a 100% Pure Java driver (also known
as a "Type IV" driver), including Oracle, Sybase, Informix, etc. Check
the documentation for your database engine for installation
instructions.