TABLE OF CONTENTS
How does the performance of JSP pages compare with that of servlets? How does it compare with Perl scripts?
What’s a better approach for enabling thread-safe servlets and JSPs? SingleThreadModel Interface or Synchronization?
How can I further optimize my servlets?
How do I set my CLASSPATH for servlets?
Why doesn’t my servlet work inside a <SERVLET> tag?
How do I fully shut down the server? My browser says “the server returned an invalid or unrecognized response” — what gives?
What is the HelloWorld Servlet?
How do I get the name of the currently executing script?
How do I mix JSP and SSI #include?
How do I ensure that my servlet is thread-safe?
How do I use Session Tracking?
How can I detect whether the user accepted my cookie?
How do I integrate HTML design into my Servlet? How do I send email from a servlet?
Are there any ISPs that will host my servlets?
What is the difference between URL encoding and URL rewriting?
How can my applet communicate with my servlet?
How can I debug my servlet? How do I create an image (GIF, JPEG, etc.) on the fly from a servlet?
How do I upload a file to my servlet?
How do I access a database from my servlet?
How does the performance of JSP pages compare with that of servlets? How does it compare with Perl scripts?
The performance of JSP pages is very close to that of servlets. However, users may experience a perceptible delay when a JSP page is accessed for the very first time. This is because the JSP page undergoes a “translation phase” wherein it is converted into a servlet by the JSP engine. Once this servlet is dynamically compiled and loaded into memory, it follows the servlet life cycle for request processing. Here, the jspInit() method is automatically invoked by the JSP engine upon loading the servlet, followed by the _jspService() method, which is responsible for request processing and replying to the client. Do note that the lifetime of this servlet is non-deterministic – it may be removed from memory at any time by the JSP engine for resource-related reasons. When this happens, the JSP engine automatically invokes the jspDestroy() method allowing the servlet to free any previously allocated resources.
Subsequent client requests to the JSP page does not result in a repeat of the translation phase as long as the servlet is cached in memory, and are directly handled by the servlet’s service() method in a concurrent fashion (i.e. the service() method handles each client request within a seperate thread concurrently.)
There have been some recent studies contrasting the performance of servlets with Perl scripts running in a “real-life” environment. The results are favorable to servlets, especially when they are running in a clustered environment. For details, see:
http://www.objexcel.com/workingjava.htm#Web Server Benchmarks
What’s the difference between the JSDK and the JSWDK? And what’s the current version?
The kit for developing servlets, containing the Servlet API classes and tools, used to be called the Java Servlet Development Kit (JSDK). Then Sun renamed the Java Development Kit (JDK) to the Java 2 Software Development Kit (J2SDK). Since J2SDK sounds a lot like JSDK, the Servlet team renamed JSDK to JavaServer Web Development Kit (JSWDK). (They also added support for JSPs.)
Here’s where it gets confusing. When they renamed it, they also renumbered it. So the JSWDK 1.0 is actually more recent than the JSDK 2.1. It’s also confusing that when people want to develop servlets, they have to download something called a JavaServer Web Development Kit, which sounds like it should be used to develop servers, not servlets.
A further confusion is that the Servlet spec is developed independently from the JSP spec, and they both have different versions than the JSDK/JSWDK.
The following table summarizes the confusion.
| Product | Version | Servlet spec | JSP spec |
| Tomcat | 3.0 | 2.2 | 1.1 |
| JSWDK | 1.0.1 | 2.1 | 1.0.1 |
| JSDK | 2.1 | 2.1 | none |
| JSDK | 2.0 | 2.0 | none |
Make sure you look for the “W”!
Can a servlet maintain a JTA UserTransaction object across multiple servlet invocations?
No. A JTA transaction must start and finish within a single invocation (of the service() method). Note that this question does not address servlets that maintain and manipulate JDBC connections, including a connection’s transaction handling.
What’s a better approach for enabling thread-safe servlets and JSPs? SingleThreadModel Interface or Synchronization?
Although the SingleThreadModel technique is easy to use, and works well for low volume sites, it does not scale well. If you anticipate your users to increase in the future, you may be better off implementing explicit synchronization for your shared data. The key however, is to effectively minimize the amount of code that is synchronzied so that you take maximum advantage of multithreading.
Also, note that SingleThreadModel is pretty resource intensive from the server’s perspective. The most serious issue however is when the number of concurrent requests exhaust the servlet instance pool. In that case, all the unserviced requests are queued until something becomes free – which results in poor performance. Since the usuage is non-deterministic, it may not help much even if you did add more memory and increased the size of the instance pool.
How can I further optimize my servlets?
You can always wring out some efficiency by making use of a StringBuffer or ByteArray.
For example, instead of sending your HTML to the client using a PrintWriter or some other output stream, you can write it out to a StringBuffer, and send it to the client using just one write invocation. Of course, you’ll have to indicate the length of your data stream in the HTTP header too as shown below:
PrintWriter out = res.getWriter();
StringBuffer sb = new StringBuffer();
…
//concatenate html to StringBuffer
//set len and write it out
res.setContentLength(sb.length());
out.print(sb);
How do I set my CLASSPATH for servlets?
That depends.
For developing servlets, just make sure that jsdk.jar (in the lib subdirectory of the JSDK (http://java.sun.com/products/servlet/) ) is in your CLASSPATH, and use your normal development tools (javac and so forth).
For running servlets, you need to set the CLASSPATH for your servlet engine. This varies from engine to engine. Each has different rules for how to set the CLASSPATH, which libraries and directories should be included, and which libraries and directories should be excluded. Note: for engines that do dynamic loading of servlets (e.g. JRun, Apache Jserv), the directory containing your servlet class files shoud not be in your CLASSPATH, but should be set in a config file. Otherwise, the servlets may run, but they won’t get dynamically reloaded.
The Complete CLASSPATH Guide for Servlets (http://www.meangene.com/java/classpath.html) by Gene McKenna (mckenna@meangene.com) has detailed instructions on how to set your CLASSPATH for JavaWebServer and JRun.
Is it the “servlets” directory or the “servlet” directory?
For Java Web Server:
- on the file system, it’s “servlets”
c:JavaWebServer1.1servletsDateServlet.class - in a URL path, it’s “servlet”
http://www.stinky.com/servlet/DateServlet
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 + “!”);
}
}
This code responds to an invocation of the form
http://myserver.foo.com/servlet/HelloHttpServlet?name=Fred
How do I get the name of the currently executing script?
Use req.getRequestURI() or req.getServletPath(). The former returns the path to the script including any extra path information following the name of the servlet; the latter strips the extra path info. For example:
| URL | http://www.purpletech.com/servlets/HelloEcho/extra/info?height=100&width=200 |
| getRequestURI | /servlets/HelloEcho/extra/info |
| getServletPath | /servlets/HelloEcho |
| getPathInfo | /extra/info |
| getQueryString | height=100&width=200 |
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.
- 6. If you absolutely can’t deal with synchronizing, you can declare that your servlet “implements SingleThreadModel”. This empty interface tells the web server to only send one client request at a time into your servlet. From the JavaDoc: “If the target servlet is flagged with this interface, the servlet programmer is guaranteed that no two threads will execute concurrently the service method of that servlet. This guarantee is ensured by maintaining a pool of servlet instances for each such servlet, and dispatching each service call to a free servlet. In essence, if the servlet implements this interface, the servlet will be thread safe.” Note that this is not an ideal solution, since performance may suffer (depending on the size of the instance pool), plus it’s more difficult to share data across instances than within a single instance.
- 7. To share data across successive or concurrent requests, you can use either instance variables or class-static variables, or use Session Tracking.
- 8. The destroy() method is not necessarily as clean as the init() method. The server calls destroy either after all service calls have been completed, or after a certain number of seconds have passed, whichever comes first. This means that other threads might be running service requests at the same time as your destroy() method is called! So be sure to synchronize, and/or wait for the other requests to quit. Sun’s Servlet Tutorial has an example of how to do this with reference counting.
- 9. destroy() can not throw an exception, so if something bad happens, call log() with a helpful message (like the exception). See the “closing a JDBC connection” example in Sun’s Tutorial.
How do I use Session Tracking?
See section 2.3 of the Servlet Essentials tutorial (http://www.novocode.com/doc/servlet-essentials/) . Also see The Session Tracking API (http://webreview.com/wr/pub/1999/01/08/bookshelf/index.html) , excerpted from Java Servlet Programming (http://www.oreilly.com/catalog/jservlet/) by Jason Hunter (http://webreview.com/wr/pub/au/Hunter_Jason).
A point I haven’t seen emphasized enough is that you should only add objects that are serializable to an HttpSession. Specifically, a JDBC Connection object is not serializable, so should not be added to the session (despite the example in Jason Hunter’s otherwise admirable Java Servlet Programming). If you’d like to associate a connection with a session, then store some arbitrary, unique handle in the session, then use that to key off your own hashtable of connections. (Make sure upon retrieval that the returned connection is not null, and if it is, create a new connection!)
The reason is that sessions may, at the whim of the server, be swapped out to disk, in order to save memory or reboot the server. This behavior can be disabled by setting a configuration parameter in your server or servlet engine. (I can’t remember offhand what these are — please email me if you know.) From the spec: Some servlet engine implementations will persist session data or distribute it amongst multiple network nodes. For an object bound into the session to be distributed or persisted to disk, it must implement the Serializable interface.
How can I detect whether the user accepted my cookie?
Here’s a clever trick: use a redirect. Drop a cookie on the HttpServletResponse object, then call resp.sendRedirect() to a “phase two” servlet. The “phase two” servlet then tests whether the cookie was sent back to it. If so, that means the user accepted the cookie the first time; if not, it means that either the client rejected the cookie, or the browser doesn’t support cookies.
Note that this technique only works if the “phase two” servlet is hidden from the user; if the user can jump directly to the test phase, then the servlet can’t tell the difference between newly-arrived clients and cookie-unfriendly clients. That means you should send a redirect from the test phase, to make sure the user doesn’t have a chance to bookmark the test phase’s URL.
Alex Chaffee (http://www.stinky.com/alex/, alex@jguru.com) has written a Servlet that demonstrates this technique called CookieDetector (http://www.purpletech.com/code/CookieDetector.html)
How do I integrate HTML design into my Servlet?
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 countless pages in your web site.
Con: your servlet code still has to hardcode HTML if it wants to be powerful (see item B, SSI).
D. JSP Java Server Pages. You write files in HTML format, and embed actual Java code inside the HTML. This is kind of like using JavaScript, only it’s on the server, and it’s real Java. This is directly parallel to Microsoft’s ASP.
Pro: it’s really cool; you only need a single file to do both UI and layout code; you don’t have to type “println” so much.
Con: if you do anything interesting, then your HTML designers will get really confused looking at the interlaced Java and HTML code — so make sure to put the complicated code inside a JavaBean where it belongs, not in the JSP page.
The new version of the JSP spec has lots of features for integrating with JavaBeans, which is a great way to separate user interface (JSP) from data and business logic (beans). See also the JSP FAQ (see our References section for a link).
Halcyon Software has a product called Instant ASP, which allows you to execute Microsft IIS-style ASPs (including code in VBScript, Jscript, Perl, Java, and JavaScript) in any Servlet Engine. Also Live Software has CF_Anywhere, which executes Cold Fusion CFML pages. See the References section for links.
E. Write your own page parser. If for some reason you’re not happy with the standard mechanisms for doing templates (see B-D above), you can always write your own parser. Seriously. It’s not rocket science.
F. HTML Object Model Class Libraries e.g. htmlKona, XML. With these class libraries, you write code and build an object model, then let the objects export HTML. This doesn’t really work for complicated layouts — and forget about letting your designer use an HTML editor — but it can be useful when you have a highly dynamic site generating HTML, and you want to automate the process. Unfortunately, you still have to learn HTML, if only to understand and validate the output. See the References section of this FAQ for a listing of some class libraries that can help.
G. Do it all yourself Develop a database-driven content management system. Think C|Net. It has a lot of standard content, but the database is king. HTML designers have little pieces of the page that they can play with, but ultimately they’re just putting content into a database, and the site (servlet) is generating every page request dynamically. 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:
- The Sphere (http://www.thesphere.com/)
- Centralogic (http://www.centralogic.com/)
- Electronaut (http://www.electronaut.com/)
Daniel Kehoe (kehoe@fortuity.com) has had “very happy experiences” with Silicon Valley Web Hosting (http://www.svwh.net/) for several clients.
(http://www.servlets.net) is an ISP geared towards hosting servlets.
Please report any experiences, good or bad, you have with these services to &feedback;.
]
What is the difference between URL encoding and URL rewriting?
URL Encoding is a process of transforming user input to a CGI form so it is fit for travel across the network — basically, stripping spaces and punctuation and replacing with escape characters. URL Decoding is the reverse process. To perform these operations, call java.net.URLEncoder.encode() and java.net.URLDecoder.decode() (the latter was (finally!) added to JDK 1.2, aka Java 2).
Example: changing “We’re #1!” into “We%27re+%231%21″
URL Rewriting is a technique for saving state information on the user’s browser between page hits. It’s sort of like cookies, only the information gets stored inside the URL, as an additional parameter. The HttpSession API, which is part of the Servlet API, sometimes uses URL Rewriting when cookies are unavailable.
Example: changing <A HREF=”nextpage.html”> into
<A HREF=”nextpage.html;$sessionid$=DSJFSDKFSLDFEEKOE”> (or whatever the actual syntax is; I forget offhand)
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#rewrite-more-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.
On my first servlet project, I used a ton of log messages for debugging.
This is my second servlet project, and this debugging technique has enhanced my productivity many folds. I am able to set code break points, step through each line of code, inspect all the objects visible to this class as well as view the objects in the current stack. I can also view, suspend, resume threads.
The setup instructions are at: (http://www.ibm.com/java/education/server-side/server-side.html)
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 engine setups, the servlet directory is not accessible by the web server, only by the servlet engine, which means you won’t be able to access it through an http:// URL.) You can either send an IMG tag in the HTML your servlet is outputting, or send an HTTP redirect to make the browser download the image directly (as its own page). (CookieDetector (http://www.purpletech.com/code/CookieDetector.html) has an example, with source code, of sending a redirect.)
Pro: the image can be cached by the browser, and successive requests don’t need to execute the servlet again, reducing server load.
Con: the image files will never be deleted from your disk, so you’ll either have to write a script to periodically clean out the images directory, or go in and delete them by hand. (Or buy a bigger hard disk
). - 2. Output the image directly from the servlet. You do this by setting the Content-type header to image/gif (for GIFs), or image/jpeg (for JPEGs). You then open the HttpResponse output stream as a raw stream, not as a PrintStream, and send the bytes directly down this stream using the write() method.
Focus on Java (http://java.miningco.com/library/weekly/aa090299.htm) has a brief article describing the use of the Java 2 JPEGCodec class.
How do I upload a file to my servlet?
From Thomas Moore’s Servlet FAQ:
Form-based file upload requires a couple of steps.
The server must supply (and the client must support) encoding type multipart/form-data. Most current browsers do, but it’s not a guarantee. Secondly (and this is usually the trickiest part), your servlet has to parse the binary data and do something with it (e.g., write it to a file on the server).
The intrepid programmer is referred to RFC 1867 for cluefulness on how to parse this data. Less brave souls can use either Jason Hunter’s implementation of a MultipartRequest (available from http://www.servlets.com), or CParseRFC1867 (available from http://www.servletcentral.com).
Note that the source code is available for both of these examples, but both assume that you will be writing the file to a file on the server. 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.
No related posts.
Tags: Java, servlet questions, Servlets, Servlets FAQ, Technical, useful answers