Servlets FAQ

Page 1 of 31

Servlets FAQ
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. 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 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. 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). 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. Note that you need not (and should not) synchronize on local data or parameters. And especially you shouldn't Mohan

2. 3.

4.

Servlets FAQ synchronize the service() method! (Or doPost(), doGet() et al.) 5.

Page 2 of 31

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. 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. To share data across successive or concurrent requests, you can use either instance variables or class-static variables, or use Session Tracking. 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. 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.

6.

7. 8.

9.

How do I use Session Tracking? That is, how can I maintain "session scope data" between servlets in the same application? Session Tracking is one of the most powerful features of Servlets and JSP. Basically, the servlet engine takes care of using Cookies in the right way to preserve state across successive requests by the same user. Your servlet just needs to call a single method (getSession) and it has access to a persistent hashtable of data that's unique to the current user. Way cool. 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 response.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. 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.) 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. Mohan

Servlets FAQ

Page 3 of 31

B. Server Side Includes (SSI). Use the 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? 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. 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/)

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 Mohan

Servlets FAQ

Page 4 of 31

<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. As far as the servlet is concerned, the applet is just another HTTP client. (Of course, you can write a servlet that is meant to be called only by your applet, in which case it *does* know the difference. You can also open a ServerSocket on a custom TCP port, and have your applet open a Socket connection. You must then design and implement a custom socket-level protocol to handle the communication. This is how you could write, e.g., a Chat applet communicating with a servlet. In general, a custom protocol requires more work than HTTP, but is more flexible. However, custom protocols have a harder time getting through firewalls.) How can I debug my servlet? 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(""); out.print(sw.toString()); out.println(""); } 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 Mohan

Servlets FAQ

Page 5 of 31

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. (Note that Tomcat does not have a replacement for servletrunner :-(.) 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 Purple Servlet References 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). You can use the Java 2 JPEGCodec class, or Acme Labs' GIFEncoder class, to turn a Java Graphics into an image file or bytestream. (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. Mohan

Servlets FAQ

Page 6 of 31

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 Purple Servlet References). 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="/myservlet"> <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. Since opening a connection to a database can take a relatively long time (upwards of 10 seconds or more), you probably don't want to create the connection in your doGet method. Instead, create the connection in the init() method and save it in an instance variable. Remember to close the connection in your destroy() method. Alternately, you could use a Connection Pool, which opens several database connections at once, then doles them out to individual threads as needed. This solves a number of problems with the one-connection method outlined above (basically, it's better at dealing with multiple simultaneous requests and with transactions). A good free connection pool implementation is available at Java Exchange (http://www.javaexchange.com/) . Connection pools also ship with many popular application servers, including BEA WebLogic (http://weblogic.beasys.com/) (formerly Tengah). This product is also available separately as jdbcKona (http://www.weblogic.com/docs/classdocs/API_jdbc.html) More information on Connection Pooling is available at the JSP FAQ, Question 13 (http://www.esperanto.org.nz/jsp/jspfaq.html#q13) . An interesting article on connection pools is at http://webdevelopersjournal.com/columns/connection_pool.html.

From the tomcat-user mailing list, here is some code for storing a JDBC connection in an instance variable: import import import import java.io.*; javax.servlet.*; javax.servlet.http.*; java.sql.*;

public final class YourClass extends HttpServlet { Connection con = null; public void init() throws ServletException Mohan

Servlets FAQ { String url = getServletContext().getInitParameter("url"); String uid = getServletContext().getInitParameter("uid"); String pwd = getServletContext().getInitParameter("pwd"); try { //Register the JDBC driver Class.forName("oracle.jdbc.driver.OracleDriver"); } catch( Exception e ) { e.printStackTrace(); }//end catch //Get a connection to the database try { con = DriverManager.getConnection(url, uid, pwd); } catch( Exception e ) { e.printStackTrace(); }//end catch }//end init() public void destroy() { try { //Close the connection to the database con.close(); } catch( Exception e ) { e.printStackTrace(); } }

Page 7 of 31

public void doGet(HttpServletRequest req,HttpServletResponse res)throws ServletException, IOException{ try { [...] Statement st = con.createStatement(); [ more JDBC code ] } catch (SQLException e) { [ ... ] } } How do I prevent the output of my JSP or Servlet pages from being cached by the browser? You will need to set the appropriate HTTP header attributes to prevent the dynamic content output by the JSP page from being cached by the browser. Just execute the following scriptlet at the beginning of your JSP pages to prevent them from being cached at the browser. You need both the statements to take care of some of the older browser versions. % response.setHeader("Cache-Control","no-store"); //HTTP 1.1 response.setHeader("Pragma","no-cache"); //HTTP 1.0 response.setDateHeader ("Expires", 0); //prevents caching at the proxy server %> However, please note that there are some problems with disabling page caching under IE 5.0 due to the unique buffering requirements of the browser. Please see the Microsoft knowledge base for details: http://support.microsoft.com/support/kb/articles/Q222/0/64.ASP http://support.microsoft.com/support/kb/articles/Q234/2/47.ASP What version of the servlet API is supported within the beta release of J2EE reference implementation? The beta version of the reference implementation supports Servlets 2.2 API Mohan

Servlets FAQ

Page 8 of 31

Show me an example of POST request chaining using JSPs and servlets The following code example demonstrates how request chaining can be implemented using a combination of JSPs and servlets. Consider the following JSP page, say Bean1.jsp, which essentially instantiates the bean fBean, places it in the request, and forwards the call to the servlet JSP2Servlet. Observe the way the bean is instantiated - here we automatically call the bean's setter methods for properties which match the names of the posted form elements, while passing the corrosponding values to the methods. <html> <body> <jsp:useBean id="fBean" class="govi.FormBean" scope="request"/> <jsp:setProperty name="fBean" property="*" /> <jsp:forward page="/servlet/JSP2Servlet" /> </body> </html> The servlet JSP2Servlet now extracts the bean passed to it from the request, makes changes using the appropriate setters, and forwards the call to another JSP page Bean2.jsp using a request dispatcher. Note that this servlet, acting as a controller, can also place additional beans if necessary, within the request. public void doPost (HttpServletRequest request, HttpServletResponse response) { try { FormBean f = (FormBean) request.getAttribute ("fBean"); f.setName("Mogambo"); // do whatever else necessary getServletConfig().getServletContext(). getRequestDispatcher("/jsp/Bean2.jsp"). forward(request, response); } catch (Exception ex) { ... } } The JSP page Bean2.jsp can now extract the bean fBean (and whatever other beans that may have been passed by the controller servlet) from the request and extract its properties. <html> <body> Within JSP2 <P> <jsp:useBean id="fBean" class="govi.FormBean" scope="request"/> <jsp:getProperty name="fBean" property="name" /> </body> </html> 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); 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 nondeterministic, it may not help much even if you did add more memory and increased the size of the instance pool. 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. Mohan

Servlets FAQ

Page 9 of 31

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 Tomcat JSWDK JSDK JSDK

Version 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

Make sure you look for the "W"! 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 How can I download a file (for instance, a Microsoft Word document) from a server using a servlet and an applet? Try telling the applet to call getAppletContext().showDocument("http://foo.com/whatever/blah.doc"). That makes the browser responsible for fetching and saving the document (including putting up the "Save As" dialog). You may also want to check the web server configuration to make sure the approprate MIME-type configuration is set. If your servlet is the one fetching the document (or creating it on the fly), then it must set the MIME-type using response.setContentType("application/ms-word") or equivalent. I've installed the JSWDK and it says I've run out of environment space when I try to start the server. How do I increase the amount of environment space under Windows? The end of your CONFIG.SYS file should include a line like the following: SHELL=C:\COMMAND.COM C:\ /E:4096 /P This assumes your COMMAND.COM file is in your root level C: directory and you wish your shells to start in that directory, too. The 4096 is the new environment size. You can increase this to a larger number if that is still a problem. I need to communicate from my servlet to another independent process. Can I use the RequestDispatcher instead of opening a socket connection? No. The RequestDispatcher can only send a message to a servlet or JSP running inside the same servlet engine. You either have to open a socket, use native code, or use Runtime.exec() to spawn a process on the web server host. Can a servlet add request parameters into a request object before passing on the request to another servlet or jsp? I am currently doing this - passing a request object to a jsp. However, you need JRun to do so. JRun has some packages included which define classes called JRunServletRequest and JRunServletResponse which are extensions of HttpServletRequest and HttpServletResponse. JRunServletRequest has the method setAttribute which allows the setting of request parameters. JRunServletResponse has the method callPage which allows the JRunServletRequest to be passed to the servlet/jsp. - Joy Mangaliman (jmangaliman@dc.com) How do I call one servlet from another servlet? It depends on what you mean by "call" and what it is you seek to do and why you seek to do it. Mohan

Servlets FAQ

Page 10 of 31

If the end result needed is to invoke the methods then the simplest mechanism would be to treat the servlet like any java object , create an instance and call the mehods. If the idea is to call the service method from the service method of another servlet, AKA forwarding the request, you could use the RequestDispatcher object. If, however, you want to gain access to the instance of the servlet that has been loaded into memory by the servlet engine, you have to know the alias of the servlet. (How it is defined depends on the engine.) For example, to invoke a servlet in JSDK a servlet can be named by the property myname.code=com.sameer.servlets.MyServlet The code below shows how this named servlet can be accessed in the service method of another servlet public void service (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... MyServlet ms=(MyServlet) getServletConfig().getServletContext().getServlet("myname"); } ...

That said, This whole apporach of accessing servlets in another servlets has been deprecated in the 2.1 version of the servlet API due to the security issues. The cleaner and better apporach is to just avoid accessing other servlets directly and use the RequestDispatcher instead. How can I access or create a file or folder in the current directory from inside a servlet? Since there's no telling which directory the servlet engine was launched from, you should always use absolute pathnames from inside a servlet. Usually I pass in the root directory in an InitParameter, and create File objects relative to that directory. How can I maintain "application scope data" in Servlets or JSPs as ASPs do? In the Servlets 2.1 spec, you can set a Servlet Context Attribute. For example, getServletContext().setAttribute("counter", new foo.Counter()); . You can also access (or initialize) these Attributes as Application Scope Beans in a JSP, using the tag. Should I override the service() method? No. It provides a fair bit of housekeeping that you'd just have to do yourself. If you need to do something regardless of whether the request is e.g., a POST or a GET, create a helper method and call that at the beginning of e.g., doPost() and doGet(). What work is happening towards creating Servlet API v2.3? Check out: http://java.sun.com/aboutJava/communityprocess/jsr/jsr_053_jspservlet.html What is a servlet development framework? A 'servlet development framework' is a package which helps us create servlet-based solutions more efficiently and effectively. Basically, after you've written a bunch of servlets from scratch, you'll proabably be irked by having to do the same sorts of things over and over again. A good framework helps to minimize how much of that rot that you have to do. For example, check out: WebMacro Most Application Servers contain their own frameworks. See this question on the FAQ. How do I get the CONTENT_LENGTH of a POST request? The servlet equivlent of getting the CGI CONTENT_LENGTH variable setting is to ask the request its content length: request.getContentLength(). This will return the value as an int. Is there a mailing list for the discussion of servlets? Yes. There is a comprehensive list of mailing lists at The Purple Servlet Resource List. Be sure to check out the Sun's SERVLET-INTEREST mailing list. Subscribe by sending an email to listserv@java.sun.com with a message body of: subscribe SERVLET-INTEREST Also, check out the archive of the mailing list. How do I redirect to a popup window frame from a servlet? (Under certain circumstances I want my servlet to bust out of the frames and redirect to another servlet or page.) You can't do this directly but it is easy to do indirectly using JavaScript. Essentially you return a page that has as its onLoad event code that opens a page and gets your new data. Your servlet would create or return a page that contains: <head> ... <script language="javascript"> function bustOut(){ var newWin = window.open("the real url", ....); // params and stuff

Mohan

Servlets FAQ } window.onLoad = bustOut; //this should work but often doesn't. Lack of parens () is correct. </script> </head> <body onLoad="bustOut()"> Eat at Joe's </body> </html>

Page 11 of 31

You could set this up as a static html page to redirect to with "the real url" being encoded in a query string. If you are unclear as to how to read the query string using JavaScript I'd recommend a good JavaScript reference. O'Reilly (who else) publishes two good books that would help with this: Javascript: The Definitive Guide by David Flanagan and Dynamic HTML by Danny Goodman Which is the best servlet server or servlet engine (best performance, easiest, etc)? It depends :-) There are a lot of products, and each has advantages and disadvantages. For a more-or-less full list of servlet engines and servlet-enabled web servers, see The Purple Tech Servlet Resource List. The most popular servlet engines seem to be JRun and JServ. Both of these work inside the open-source Apache Web Server (easily the most popular HTTP server). Tomcat is the latest-and-greatest open-source servlet/JSP engine using code from Sun, Apache and JServ. ServletExec is reportedly very stable in high-volume sites -- but the other servlet engines are being used on some high-volume sites as well. If you have experience with or opinions about any of these products, please add feedback to this FAQ. Why doesn't response.sendRedirect(response.encodeURL(url)) work? Use response.sendRedirect(response.encodeRedirectURL(url)) instead. It will correctly rewrite the URL for clients that don't support cookies. How do I download a (binary, text, executable) file from a servlet or JSP? Solution 1: Just use HTTP! This has nothing to do with servlets per se. Make sure the file is on your web server. Then you can either embed a link for your user to click, as Click here to download the Runme app or have your servlet or JSP send a redirect to the file, as response.sendRedirect("http://myserver.com/files/runme.exe"); or get fancy with JavaScript (see this FAQ for inspiration). The point is -- this is still the World Wide Web! HTTP is a file transfer protocol; downloading files what it's for! Solution 2: Open the file from your servlet using java.io classes, and shove the bytes down the response stream. Make sure to set the content type to match the type of file, e.g. response.setContentType("image/gif") or response.setContentType("application/x-msword"). This technique is a little more expensive, but allows you to do things like security checks, or to access files that are on your web server host, but outside the HTTP directory structure. For source code to a servlet that "downloads" (actually it's uploading, right?) a text file, see this FAQ answer. Is the threading concurrency problem more pronunced in a multi-processor environment than in a single-processor environment? From the developer's point of view, the "concurrency problem" is simply that if your object is to be accessed from multiple threads, you need to take steps to ensure that your object is thread safe. Otherwise, your object may end up in an invalid state and may not behave as you expected. It makes no difference whether the accessor threads are running on the same processor or different processors; it is the internals of the JVM and the operating system that guarantee consistency of the address space across CPUs. Because servlets by their nature are intended to be used in a multi-client environment, they should always either implement SingleThreadModel or be designed for thread safety. Note that making a servlet thread safe does not imply that the methods need to be declared as synchronized; synchronization is just one of the many techniques that can be used to impose thread safety. See this FAQ for more information. How can I pass an object from an applet to a servlet ? Look at this article, they explain exactly how to solve your problem through Object Serialization. http://www.j-nine.com/pubs/applet2servlet/Applet2Servlet.html Have fun.

Mohan

Servlets FAQ How do I read and output a text file from a Servlet? Try the following: public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { // output an HTML page res.setContentType("text/html"); // load a configuration parameter (you must set this yourself) String root = getInitParameter("root"); // print some html ServletOutputStream out = res.getOutputStream(); out. println("<html>"); out.println("<head><title>Message of the Day</title></head>"); out.println("<body><h1>Today's Message:</h1>"); // print the file InputStream in = null; try { in = new BufferedInputStream( new FileInputStream(root + "/message.txt") ); int ch; while ((ch = in.read()) !=-1) { out.print((char)ch); } finally { if (in != null) in.close(); // very important } // finish up out.println("</body></html>");

Page 12 of 31

}

(You may have to catch an IOException -- I typed that in without compiling it...) You may want to do more than just copy the file; look in the java.io package for classes that help you process a file, like StreamTokenizer. Pay attention to the use of an InitParameter to provide a root on the file system. That way your servlet can be used on other servers without hardcoding a file path. Also note the use of a finally block to close the file. This way, even if the reading throws an exception, the file will be closed. This is important on a server, since file descriptors are limited, and you don't want any leaks, since the server will be up for a very long time (hopefully!). Whenever you access local resources, you have to consider security holes. For instance, if you make a file name based on a FORM parameter, you should validate it, to make sure if a hacker sends in, e.g., "/etc/passwd" as his user name, he won't actually get the system password file. What are the Servlet equivalents to all the CGI environment variables? The following CGI environment variables, and their descriptions, were taken from the CGI specification, at http://hoohoo.ncsa.uiuc.edu/cgi/env.html. Please see http://java.sun.com/products/servlet/2.2/javadoc/index.html for a full description of the Servlet Request object. It allows direct access to many things that are not available as CGI environment variables, including Parameters, Cookies, HTTP Headers, and Sessions. CGI Variable Servlet Request Method SERVER_SOFTWARE ? The name and version of the information server software answering the request (and running the gateway). Format: name/version SERVER_NAME getServerName() The server's hostname, DNS alias, or IP address as it would appear in self-referencing URLs. GATEWAY_INTERFACE N/A The revision of the CGI specification to which this server complies. Format: CGI/revision SERVER_PROTOCOL getProtocol() The name and revision of the information protcol this request came in with. Format: protocol/revision SERVER_PORT getServerPort() The port number to which the request was sent. Mohan

Servlets FAQ

Page 13 of 31

REQUEST_METHOD getMethod() The method with which the request was made. For HTTP, this is "GET", "HEAD", "POST", etc. PATH_INFO getPathInfo() The extra path information, as given by the client. In other words, scripts can be accessed by their virtual pathname, followed by extra information at the end of this path. The extra information is sent as PATH_INFO. This information should be decoded by the server if it comes from a URL before it is passed to the CGI script. PATH_TRANSLATED getPathTranslated() The server provides a translated version of PATH_INFO, which takes the path and does any virtual-to-physical mapping to it. SCRIPT_NAME getServletPath() A virtual path to the script being executed, used for self-referencing URLs. getQueryString() QUERY_STRING also see getParameter() , getParameterValues(), etc.. The information which follows the ? in the URL which referenced this script. This is the query information. It should not be decoded in any fashion. This variable should always be set when there is query information, regardless of command line decoding. REMOTE_HOST getRemoteHost() The hostname making the request. If the server does not have this information, it should set REMOTE_ADDR and leave this unset. REMOTE_ADDR getRemoteAddr() The IP address of the remote host making the request. AUTH_TYPE getAuthType() If the server supports user authentication, and the script is protects, this is the protocol-specific authentication method used to validate the user. REMOTE_USER getRemoteUser() If the server supports user authentication, and the script is protected, this is the username they have authenticated as. ? - but if a server supports RFC 931, REMOTE_IDENT it should probably pass this in getRemoteUser() If the HTTP server supports RFC 931 identification, then this variable will be set to the remote user name retrieved from the server. Usage of this variable should be limited to logging only. CONTENT_TYPE getContentType() For queries which have attached information, such as HTTP POST and PUT, this is the content type of the data. CONTENT_LENGTH getContentLength() The length of the said content as given by the client. The HTTP header lines received from the client, if any, are placed into the The HTTP Headers are available environment with the prefix HTTP_ followed by the header name. An through getHeader(String), example of this is the HTTP_ACCEPT variable which was defined in CGI/1.0. getHeaders(String) and Another example is the header User-Agent. getHeaderNames() HTTP_ACCEPT getHeader("Accept") The MIME types which the client will accept, as given by HTTP headers. Other protocols may need to get this information from elsewhere. Each item in this list should be separated by commas as per the HTTP spec. Format: type/subtype, type/subtype HTTP_USER_AGENT getHeader("User-Agent") The browser the client is using to send the request. General format: software/version library/version. How can my application get to know when a HttpSession is removed (when it time-outs)? Define a class, say SessionTimeoutNotifier, that implements javax.servlet.http.HttpSessionBindingListener. Create a SessionTimeoutNotifier object and add it to the user session. When the session is removed, SessionTimeoutNotifier.valueUnbound() will be called by the servlet engine. You can implement valueUnbound() to do whatever you want. Why should I use JSP when there is already servlet technology available for serving dynamic content? While JSP may be great for serving up dynamic Web content and separating content from presentation, some may still wonder why servlets should be cast aside for JSP. The utility of servlets is not in question. They are excellent for server-side processing, and, with their significant installed base, are here to stay. In fact, architecturally speaking, you can view JSP as a high-level abstraction of servlets that is implemented as an extension of the Servlet 2.1 API. Still, you shouldn't use servlets indiscriminately; they may not be appropriate for everyone. For instance, while page designers can easily write a JSP page using conventional HTML or XML tools, servlets are more suited for back-end developers because they are often written using an IDE -- a process that generally requires a higher level of programming expertise. When deploying servlets, even developers have to be careful and ensure that there is no tight coupling between presentation and content. You can usually do this by adding a third-party HTML wrapper package like htmlKona to the mix. But even this approach, though providing some flexibility with simple screen changes, still does not shield you from a change in the Mohan

Servlets FAQ

Page 14 of 31

presentation format itself. For example, if your presentation changed from HTML to DHTML, you would still need to ensure that wrapper packages were compliant with the new format. In a worst-case scenario, if a wrapper package is not available, you may end up hardcoding the presentation within the dynamic content. So, what is the solution? One approach would be to use both JSP and servlet technologies for building application systems. This answer is excerpted from my Javaworld article Understanding JavaServer Pages Model 2 Architecture Can I call a JSP, then have it return control to the original JSP, like a subroutine or method call? Yes. That is exactly the purpose served by the <jsp:include> action. The syntax of the include action is: <jsp:include page="relativeURL" flush="true" /> You can have the include action anywhere within your JSP page, and the relative URL specified for the page attribute may point to either a static (.html) or dynamic resource like a servlet or JSP. Since the include action is handled during the request processing phase, it makes since to include only resources which generate some dynamic content. The included resource is also automatically forwarded the request and response objects of the invoking JSP page. For example, the action: <jsp:include page="/examples/jsp/copyright.jsp"flush="true"/> results in the output of copyright.jsp being included inline within the response of invoking JSP page. There is however a limitation. The included JSP or servlet resource cannot change the HTTP headers. For example, they cannot set cookies, since they are sent to the browser via the HTTP headers. Can I use Tomcat or JavaWebServer as a service on NT? Near the end of the installation program you will be asked if you want to have the Java Web Server start automatically on system reboot. (That is, whether you want to install the Java Web Server as an NT Service). If you click Yes: An entry will be added to the Control Panels -> Services and the JavaWebServer NT Service will be started up automatically every time you restart your system. If you click No: No entry will be made in the Control Panel's Services panel. If you change your mind later, the product documentation provides instructions for how to setup the web server to start automatically. For instructions, see the file: [server_root]\doc\en\administration\server_start_Win.html How do you shut down JServ safely if you've started it (manual mode), such that the destroy() methods of the existing servlet classes are invoked? use the -r or -s flags. Straight from the command line usage info for java org.apache.jserv.JServ with no args: Usage: java org.apache.jserv.JServ [config file] [options] Options: -v : show version number -V : show compile settings -s : tell running ApacheJServ to shutdown -r : tell running ApacheJServ to do a graceful restart Note: please, specify the configuration file for the [-s] [-r] options. How do I send information and data back and forth between applet and servlet using the HTTP protocol? Use the standard java.net.URL class, or "roll your own" using java.net.Socket. See the HTTP spec at W3C for more detail. Note: The servlet cannot initiate this connection! If the servlet needs to asynchronously send a message to the applet, then you must open up a persistent socket using java.net.Socket (on the applet side), and java.net.ServerSocket and Threads (on the server side). Is there any way to detect the cookies from a servlet invoked by the tag from a shtml page? Because the HTTP header information is written before the embedded servlet is executed, embedded servlets cannot perform any functions which require writing to the HTTP header. For this reason, the following restrictions apply to servlets embedded in .shtml pages: • • • • • No cookies No redirects No errors or status (HttpServletResponse.sendError() or sendStatus()) No setHeader() No setting of the content length

Can I get the path of the current servlet where it lives on the file system (not its URL)? Try using: request.getRealPath(request.getServletPath())

Mohan

Servlets FAQ An example may be: out.println(request.getRealPath(request.getServletPath())); How to get the browser version and also a check if it allows cookies in a servlet? Another name for "browser" is "user agent." You can read the User-Agent header using request.getUserAgent() or request.getHeader("User-Agent")

Page 15 of 31

See this question in the JSP FAQ: http://www.jguru.com/jguru/faq/view.jsp?EID=12253 for a class which embodies lots of good info about the browser. It's not enough to tell if the browser might possibly support cookies; you also must tell if the user has enabled or disabled cookies. For that, you must drop a test cookie on the browser, then see if it gets sent back. A servlet that does this is called CookieDetector, at http://www.purpletech.com/code/. Should I use the SingleThreadModel interface or provide explicit synchronization to make my JSP pages and servlets thread safe? You can have a any servlet implement the SingleThreadModel interface. JSP pages implement this in the background when you specify <%@ page isThreadSafe="false" %> 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 synchronization for your variables. 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 nondeterministic, it may not help much even if you did add more memory and increased the size of the instance pool. How can I stress test a servlet? Allaire has a ServletKiller product available for free at http://www.allaire.com/products/jrun/ServletAddOn.cfm that will stress test your servlets. Some additional non-servlet-specific stress testing tools are e-Load from RSW Software (http://www.rswsoftware.com/products/eload.html), Microsoft's Web Application Stress Tool (http://homer.rte.microsoft.com/), and Apache's JMeter (http://java.apache.org/jmeter/index.html). How can I daisy chain servlets together such that the output of one servlet serves as the input to the next? There are two common methods for chaining the output of one servlet to another servlet : the first method is the aliasing which describes a series of servlets to be executed the second one is to define a new MIME-Type and associate a servlet as handlers As I don't really use the second one, I'll focus on the aliasing. To chain servlets together, you have to specify a sequential list of servlets and associate it to an alias. When a request is made to this alias, the first servlet in the list is invoked, processed its task and sent the ouptut to the next servlet in the list as the request object. The output can be sent again to another servlets. To accomplish this method, you need to configure your servlet engine (JRun, JavaWeb server, JServ ...). For example to configure JRun for servlet chaining, you select the JSE service (JRun servlet engine) to access to the JSE Service Config panel. You have just to define a new mapping rule where you define your chaining servlet. Let say /servlets/chainServlet for the virtual path and a comma separated list of servlets as srvA,srvB. So when you invoke a request like http://localhost/servlets/chainServlet, internally the servlet srvA will be invoked first and its results will be piped into the servlet srvB. The srvA servlet code should look like : public class srvA extends HttpServlet { ... public void doGet (...) { PrintWriter out =res.getWriter(); rest.setContentType("text/html"); ... out.println("Hello Chaining servlet"); } } All the servlet srvB has to do is to open an input stream to the request object and read the data into a BufferedReader object as for example : BufferedReader b = new BufferedReader( new InputStreamReader(req.getInputStream() ) ); String data = b.readLine(); b.close(); After that you can format your output with the data. It should work straigthforward with Java Web Server or Jserv too. Just look at in their documentation to define an alias name. Mohan

Servlets FAQ Hope that it'll help.

Page 16 of 31

Why there are no constructors in servlets? A servlet is just like an applet in the respect that it has an init() method that acts as a constrcutor. Since the servlet environment takes care of instantiating the servlet, an explicit constructor is not needed. Any initialization code you need to run should be placed in the init() method since it gets called when the servlet is first loaded by the servlet container. If I store an image as a BLOBs in my database, and I use getBinaryStream to retrieve the value, how can I show it in a browser? Use the same technique as you would use to display a file (or any other stream). See http://www.jguru.com/jguru/faq/view.jsp?EID=159 and http://www.jguru.com/jguru/faq/view.jsp?EID=3696 for more details. What are the steps involved in setting up JServ on Apache to run Servlets? The following page has got a very good document on how to install and configure apache Jserv : http://www.magiccookie.com/computers/apache-jserv/#Basic installation How to handle multiple concurrent database requests/updates when using JDBC with servlets? All the dbms provide the facility of locks whenever the data is being modified. There can be two scenarios: 1. 2. Multiple database updates on different rows, if you are using servlets the servlets will open multiple connections for different users. In this case there is no need to do additional programming. If database updates are on the same row then the rows are locked automatically by the dbms, hence we have to send requests to the dbms repeatatively until the lock is released by dbms.

This issue is dealt with in the JDBC documentation; look up "Transactions" and "auto-commit". It can get pretty confusing. How can I use servlets to make sure a user has logged in before I handle the request? Since a JSP page is nothing else than a servlet, you can look at this FAQ entry : http://www.jguru.com/jguru/faq/view.jsp?EID=16898. What is the difference between GenericServlet and HttpServlet? GenericServlet is for servlets that might not use HTTP, like for instance FTP servlets. Of course, it turns out that there's no such thing as FTP servlets, but they were trying to plan for future growth when they designed the spec. Maybe some day there will be another subclass, but for now, always use HttpServlet. How do you share session objects between servlets and JSP? Sharing sessions between a servlet and a JSP page is straight forward. JSP makes it a little easy by creating a session object and making it availabe already. In a servlet you would have to do it yourself. This is how: HttpSession session = request.getSession(true); //create a session if one is not created already now session.putValue("variable","value");//assign the session variable to a value. in the jsp page this is how you get the session value: <% session.getValue("varible"); %> Can I get at the OutputStream that is buried underneath ServletContext.log()? If so how can I modify it? Based on Sun's Java Servlet API ServletContext.log() logs messages to the servlet log file. The name and type of the servlet log file is specific to the servlet engine, but it is usually an event log. To get the log OutputStream depends on the specific servlet engine. For IBM's WebSphere, you can look in the com.sun.server.log.TraceLog class. For the J2EE SDK, the class is com.sun.enterprise.log.Log. How do I set the content encoding of the response to "x-gzip"? I am trying to send HTML data in gzip format, hoping the client will automatically deflate it Make sure you set HttpServletResponse by response.setContentType("application/x-gzip" ); A user would have the choice to open with WinZip plugin or save as WinZip file extension to be deflated later on. Very few browsers understand how to deflate this directly and display it. What happens with System.err and System.out in a servlet? It depends on the Servlet Engines. For instance, with Websphere, System.err and System.out both write output to files like this jvm_stderr and jvm_stdout. How can I include content from a URL, not from a local file? You would need to read in the content from the URL and place it in the file yourself. See http://www.jguru.com/jguru/faq/view.jsp?EID=13198 for an example of this, but use a Reader stream instead of an InputStream as you'll be working with character data. How do I setup a cookie to expire after a certain time? You can set the maximum age of a cookie with the setMaxAge(int seconds) method: • • • A positive value is the maximum number of seconds the cookie will live, before it expires A negative value means the cookie will not be stored beyond this browser session (deleted on browser close) Zero means to delete the cookie

How can I implement a password-protected servlet? Most web servers support HTTP-Authentication. Thus, once the servlet is loaded, the user has already been authenticated. You can learn more about this from: http://www.trudat.com/computer/authentication/authentication.html and http://www.trudat.com/computer/authenti.htm. Mohan

Servlets FAQ

Page 17 of 31

While I am still making changes to a servlet code, how can I make a servlet reload every time I test it? It depends on the web server you are using to test your servlet. For instance, with Tomcat, you would replace the WAR file and the server notices the chanage and loads the new servlet on the next request, without having to restart the server. What is a servlet? A servlet is a way of extending your web server with a Java program to perform tasks previously dealt with by CGI scripts or proprietary server extension frameworks. For more information, visit Sun's Servlet API home at http://java.sun.com/products/servlet/. Is there any method to unload a servlet from Web Server memory without restarting the server? There is no standard method/mechanism to unload a servlet from memory. Some servers, like JWS, provide the means to load and unload servlets from their administration module. Others, like Tomcat, require you to just replace the WAR file. How do I setup a Servlet as an RMI client (and not get an RMI Security exception in the process)? I think this depends a lot on the JDK you are using to run your Servlet Engine. • • Platform 2 (JDK 1.2, 1.3): take a look at the security policy. Refer to the documentation for setting correct java.net.SocketPermission entries, plus maybe File Access Permissions and in some cases ClassLoader permissions. Platform 1 (JDK 1.1.x): The only real way I found to circumvent my problems was to implement my own RMI SecurityManager. Therefore simply extend the java.rmi.RMISecurityManager class and implement your own policy overriding specific permission check methods. Most likely those will be: checkConnect, checkRead, checkWrite. But I suggest to examine the API doc of the RMISecurityManger to find out more.

To set that SecurityManager you have to add following line to your Servlet init() method: //set RMI Security Manager<br> System.setSecurityManager(new WebSpaceSecurityManager()); How can I use Servlets to add entries to the password list in Apache? I tried to invoke the htpasswd.exe but it doesn't work. Your servlet needs write access to the AuthUserFile specified in the access file (Check the Apache Documentation on that). Then you need some utility implmenting a standard C crypt() in Java. Those are freely available from different Java resource pages. Now just open the file and append(!) a line that has the following format: [username]:[crypted password] Don't forget there are certain security issues regarding what you want to do. I would not recommend to do this within security sensible environments. I have stored image files in a database. Is there any way to display that image in a web browser by querying the database? I would recommend you to retrieve the image via JDBC from a simple HTTP servlet. Things you have to take care about: • • • Ensure to set the correct Mime type. This has to be done calling HttpServletResponse.setContentType(String type); e.g. myHttpServletResponse.setContentType("image/jpeg"); Ensure that your RDBMS does not limit result sizes (i.e. check the manuals if you get half images, and always the same block sizes). Attach ?<param>=<value> to your src URL to specify the picture to be retrieved. This param can be retrieved within your service method very simple, using: HttpServletRequest.getParameter(String name); The HTML tag for the image would then be something like follows: <img src="http://www.mydomain.com/PictureServlet?id=35"> (Sure you can use more params if you need to do so.) Use some simple or sophisticated caching algorithm to limit your systems load.

Be sure to check the Servlet FAQ for questions on Servlets. I've just set up Tomcat 3.1, created a context, and when I try and run a sample JSP page, I get: Error: 500, Internal Servlet Error: java.lang.NullPointerException You forgot to create a classes folder located at: <context>/WEB-INF/classes Create the folder, restart tomcat, all should be well. How can I load a DLL (native library) and run something inside the DLL from a Servlet using JNI on JavaWebServer in Windows NT? Is there anything special about JavaWeb Server so only JNI is not working? Probably not, all you have to do is to learn how to use JNI. I used "Essential JNI" by Rob Gordon. What is a cookie? See http://www.cookiecentral.com/faq/ and these FAQ answers. Where can I find an online servlet tutorial? There's a pretty good one here. How do I make Tomcat 3.1 invoke my servlets via the url <host>/ servlets/<class> instead of <host>/ servlet/<class> that it's doing now? Change the url-pattern of the default servlet invoker located in the "deployment descriptor" for your web application. This file us usually located in <context>/WEB-INF/web.xml file. Replace: Mohan

Servlets FAQ /servlet/* with: /servets/*

Page 18 of 31

Also note that in Tomcat 3.1, web applications begin with the default "deployment descriptor" located in <tomcat home dir>/conf/web.xml. You can change the "default" for all web applications there. What distinguishes a JavaBean from a Servlet? JavaBeans are a set of rules to follow to create reusable software components, or beans. This contains properties and events. At the end you have a component which could be examined by a program (like an IDE) to allow the user of your JavaBean component to configure it and to run in its Java programs. Servlets are Java classes running in a Servlet engine implementing a particular interface: Servlet, forcing you to implement some methods (service()). The servlet is an extension of your web server where this servlet is running on and only lets you know when a user requests a GET or POST calls from a web page to your servlet. So, both have nothing in common except Java. Is there a standard place to write temporary files needed for servlets? Prior to the Servlets 2.2 API, there was no standard location. The 2.2 API adds the javax.servlet.context.tmpdir attribute to the servlet context that defines where to write something: File directory = (File)getServletContext().getAttribute("javax.servlet.context.tmpdir"); File file = File.createTempFile("prefix", ".tmp", directory); FileWriter out = new FileWriter(file); Where does the output of System.out and System.err go in a servlet? out and err should go to console for Java-based servlet engines. Some servlet engines (a.k.a. containers in Servlets 2.2) block System.out and System.err for servlets, so you may want to use ServletContext.log() or use your own log function. Some servlet engines have special property to disable/enable output to standard streams for servlets. How do I limit the number of simultaneous requests to my servlet? It is a servlet engine parameter, for instance JRun allows you to set up the number of maximum concurrent threads. How much data we can store in a session object? Any amount of data can be stored there because the session is kept on the server side. The only limitation is sessionId length, which shouldn't exceed ~4000 bytes - this limitation is implied by HTTP header length limitation to 4Kb since sessionId may be stored in the cookie or encoded in URL (using "URL rewriting") and the cookie specification says the size of cookie as well as HTTP request (e.g. GET /document.html\n) cannot be longer then 4kb. Where can I find out more info about WAR (Web Archive) files? The JSP Spec v 2.2 is a good starting point. http://java.sun.com/products/servlet/2.2 When you communicate with a servlet from an Applet, how can you ensure that the session information is preserved? That is, how do you manage cookies in applet-servlet communication? For sessions, your best bet is to have the servlet rewrite the URLs to include the session information. As far as cookies go, I believe the only way to do this from an applet is if you opened up the Socket connection yourself to speak HTTP, and read/set the headers yourself. While you can get the headers from an URL Connection, unless you install a custom socket factory, I'm not sure how you can set the headers to pass the cookies back. How do I use the DLLs from Tomcat to Servlet-enable IIS? Look at the Tomcat IIS How to file located at the address : http://jakarta.apache.org/cvsweb/index.cgi/jakarta-tomcat/etc/tomcat-iis-howto.html Can an ASP page call Servlets or JSP, and vice versa? ASP works only in IIS and Apache Server. It is also possible for these web servers to run servlet programs by using a specific servlet engine. You can invoke a servlet program from ASP be redirecting the request to the URL of the servlet. How can you logout a user (invalidate his Session) when a user directly closes his browser window? Short answer: you can't. Fortunately, sessions expire automatically after a period of time; check your servlet engine documentation to see how to set this timeout period. I felt that there should be a way to do it from JavaScript; unfortunately, JavaScript doesn't seem to have an onWindowClose handler. JavaScript expert Daniel Zen of Zen Digital writes: There is no onClose handler, it is the onUnload handler that you want. The problem is you want a page to be 'loaded' when the window is closing. In order to load a page you have to have a window.... So you would have to somehow abort the close (I don't know if this is possible), or open a new window with your URL, and rely on that document to close it's own window (which I have seen pop up a dialog box warning on occasion...) which won't work if javascript is disabled. Also, the onUnload handler only works in IE. If anyone figures out a way to make this work, please let us know. P.S. Thanks to the many people who submitted answers!

Mohan

Servlets FAQ

Page 19 of 31

Is there a way I can set my servlets to do thread pooling? Not really. You shouldn't be concerned about thread management when writing a servlet. Leave that up to the servlet engine. It may be using techniques like thread pooling, load balancing, and activation/passivation strategies to optimize performance. In fact, most EJB servers do use thread pooling "behind the scenes." All you need to worry about as a servlet author is that your servlets are thread-safe. See this FAQ for more details on thread safety and servlets. If you want to spawn threads on your own, say to run a chat server, you may use thread pooling, but make sure you understand the interaction with the servlet engine. How can I create a servlet that will initialize connections to different systems, in a way that other servlets can use them? If you want to share data between servlets, you can use Attributes. See the documentation on ServletContext for more information. If you want to open up, for example, several JDBC connections that will be shared among several servlets, you can define a "behind the scenes" initialization servlet that has an init() method that opens the connections and adds them as Attributes. You then configure your servlet engine to initialize that servlet on startup (rather than on request). That way as soon as the engine boots, your init servlet will run and open the connections. (This servlet may never be called on its own! You can leave the service method undefined, or provide status or debugging information.) Also, naturally, you should remember to close the connections in the servlet's destroy method. Does JSWDK (Sun Webserver Dev Kit) support servlet chaining? Do any servlet engines? Servlet Chaining was a feature of several early servlet engines, but has been removed from the spec. There has been some talk of officially adding it, but for now, servlets must explicitly "chain" by using RequestDispatcher. I believe JRun and Java Web Server both support servlet chaining (in non-standard ways, naturally). If you know of any others that do, please submit a feedback. What is the difference between the doGet and doPost methods? doGet is called in response to an HTTP GET request. This happens when users click on a link, or enter a URL into the browser's address bar. It also happens with some HTML FORMs (those with METHOD="GET" specified in the FORM tag). doPost is called in response to an HTTP POST request. This happens with some HTML FORMs (those with METHOD="POST" specified in the FORM tag). Both methods are called by the default (superclass) implementation of service in the HttpServlet base class. You should override one or both to perform your servlet's actions. You probably shouldn't override service(). What is the difference between encodeRedirectUrl and encodeURL? encodeURL and encodeRedirectURL are methods of the HttpResponse object. Both rewrite a raw URL to include session data if necessary. (If cookies are on, both are no-ops.) encodeURL is for normal links inside your HTML pages. encodeRedirectURL is for a link you're passing to response.sendRedirect(). It has slightly different syntax requirements too gory to get into here. See this FAQ for more details. Can I use System.exit() in servlets? Gack! No no no no no... At best, you'll get a security exception. At worst, you'll make the servlet engine, or maybe the entire web server, quit. You don't really want to do that, huh? :-) I am opening a single JDBC connection in my init() method. Do I need to synchronize on the Connection or the Statement object? You shouldn't have to. If your JDBC driver supports multiple connections, then the various createStatement methods will give you a thread-safe, reentrant, independent Statement that should work OK, even if other requests/threads are also accessing other Statements on the same Connection. Of course, crossing your fingers never hurts... Many early JDBC drivers were not re-entrant. The modern versions of JDBC drivers should work OK, but there are never any guarantees. Using connection pooling will avoid the whole issue, plus will lead to improved performance. See this FAQ for more information. How can I determine the name and version number of the servlet or JSP engine that I am using? From within a servlet, you can invoke the ServletContext.getServerInfo() method as follows: String thisServer= getServletConfig().getServletContext().getServerInfo(); If you are using JSP, you can use this expression: <%= application.getServerInfo() %> Can a Servlet access an SAP database? Yes you can. SAP has provided classes for its BAPI methods that you can you use in your servlets. Those are available from your SAP front-end CD. Also you will be needing middleware to connect to SAP from your servlets. Mohan

Servlets FAQ

Page 20 of 31

What is the return type of ServletRequest.getAttribute( "javax.servlet.request.X509Certificate" ), the method of retrieving client certificates in the Servlet 2.2 API? According to the Servlet Specification 2.2 (not the generated API documents, which are vague on the matter), the object returned is an array of type java.security.cert.X509Certificate. How can I plot data on a graph in a servlet? The KavaChart software, a commercial Java based solution for charts and graphs, is the only servlet based solution of which I am aware. How can I invoke a servlet from JavaScript? Yes, and it is quite easy. You just have to remember that a servlet is seen by the browser like a normal web page with its URL. Just call it lke you would call a web page. It is also possible to use servlet data in javascript without changing page. For example I am using Microsoft XML data islands that get XML data from a servlet. CODE: <SCRIPT> function display() { data.transformNodeToObject(ss.XMLDocument, resultTree.XMLDocument); document.write(resultTree.xml); } </SCRIPT> <SCRIPT FOR="window" EVENT="onload"> data.async = false; data.load("../servlet/SQLResult"); ss.async = false; ss.load("MyStyleSheet.xsl"); display(); </SCRIPT> <XML id="data"></XML> <XML id="ss"></XML> <XML id="resultTree"></XML>

Here "../servlet/SQLResult" is a servlet URL. What is the difference between Java Servlets and Java Server Pages (JSP)? Short answer: a JSP is a Servlet that thinks it's a Web page. Medium answer: Both use server-side Java to dynamically generate web pages. The source code to a JSP looks like HTML, with Java embedded inside funny tags; the source code to a servlet looks like Java, with HTML embedded in out.print(...) statements. Both use the Servlet API to communicate with the web server and the client. In fact, a JSP gets compiled into a servlet, so they're almost identical in terms of expressive power. The choice is, whether you're more comfortable coding your pages in Java or in JSP-style HTML; and since you can call a JSP from a Servlet and vice versa, you don't have to make an either-or decision. Long answer: See the Servlet FAQ and the JSP FAQ for all the information you need about both technologies. What is server push? How do I use it from a servlet? To understand what "server push" means you must remember that the web operates in an event-driven way; the events can come from clients or servers. • • In the normal Web client-server scenario, the browser asks the server for the web pages. This is called "pull", because the client "pulls" the data from the server. The events, in this case, come from the client. Sometimes it is necessary to have the server send data to the client; a typical case is that of stock data, which must change constantly on the web page to remain in sync with actual data, even if the client doesn't request it by clicking on a request button. This is called "push", because the server "pushes" the data to the client. The events, in this case, come from the server.

[However, even with so-called server-push, the server cannot actually initiate a TCP connection to the client. Instead, the server leaves the initial connection open; after the first chunk of data (a whole page, or a partial page, or a single image) is sent, the client is then waiting around for the server to send the next piece of information. Note that this means that the server has to keep its sockets open, which can be expensive. Using an HTML Refresh (e.g. <META HTTP-EQUIV="Refresh" CONTENT="4;URL=http://www.justobjects.nl">) may be a better solution. -Alex] On Javaworld you can find an explanation on how to implement server push with servlets in Pushlets, Part 1: Send events from servlets to DHTML client browsers. It describes of a pushlet framework.You may visit the pushlet Website through http://www.justobjects.nl/ to see how development is progressing, to run examples, and to download the framework source. Mohan

Servlets FAQ

Page 21 of 31

Can I include a static HTML file in a servlet response using the RequestDispatcher? Yes. In the following code, pageName is a String containing the URL to include. String encodedPageName = response.encodeUrl(pageName); this.getServletConfig().getServletContext().getRequestDispatcher(encodedPageName).include(request, response); Why doesn't Tomcat shut down when I run shutdown.bat (or shutdown.sh)? One possibility is that if you disabled the Apj12 connector in your server.xml you have also disabled the mechanism by which Tomcat shutdown is executed -- try putting that back in if you've commented it out. (Thanks to Craig McClanahan from the Tomcat User Mailing List.) How do I build Apache with DSO support, to use Tomcat and mod_jserv? You have to add the '--enable-module=so' option to your 'configure' call in order to enable DSO, i.e.: ./configure --prefix=/usr/local/apache --enable_rule=SHARED_CORE --enable-module=so (Thanks to Peter Theill from the Tomcat User Mailing List.) Where do I find documentation for the web.xml and server.xml configuration files? For web.xml, look in the Servlet Specification, chapter 13, "Deployment Descriptor." Note that Tomcat uses the default web.xml file, located in TOMCAT_HOME/conf/web.xml, as the base for all contexts; individual webapps can override specific settings in a custom WEB-INF/web.xml file. For server.xml, look in the Tomcat distribution, in the directory you unzipped, under /doc/uguide/tomcat_ug.html -- scroll down to the "Tomcat's Configuration Files" section. When using sendRedirect, I always get a page returned stating: "Document moved." Is it possible to go directly to the redirected page? There are two possibilities. Personally I am using the Jigsaw Web Server from the World Wide Web Consortium and I do not encouter the problem: if I send a redirect the new page automatically loads. CODE: PageName is a String containing the redirect URL response.sendRedirect(PageName); Another possibility is to send a META refresh as a response page, so that the browser calls the page you want to redirect to after your response loads. To be sure, put the redirect link on the page, just in case. CODE: PageName is a String containing the redirect URL PrintWriter TempWriter = response.getWriter(); TempWriter.print("<HTML><HEAD>"+ "&lt;META HTTP-EQUIV=\"Refresh\" CONTENT=\"5";URL=\""+PageName+"\"&gt;"+ "&lt;/HEAD&gt;<BODY>Redirecting to: &lt;A href="+PageName+" \"&gt;"+PageName+"&lt;/A&gt;&lt;/BODY&gt;&lt;/HTML&gt;"); TempWriter.flush(); TempWriter.close(); Where do I store image files so my servlet's HTML pages can display them? Anywhere you want, just remember to use the correct path relative to the one of the servlet. A servlet is seen by the browser just by its URL. Browsers doesn't see the difference between a file, a servlet or a JSP. Servlets are usually grouped in a directory which is mapped to a directory URL. [You must put the image files in a directory off of the document root, which is not where the servlet class files are, but will probably be near JSP and HTML files. Alex] This is what a browser may see: -root | -servlet | | | *MyServlet | *TestServlet | -images | | | *Duke.gif | *Web.gif | -MyHtmlFiles Mohan

Servlets FAQ | *Main.html *Login.html

Page 22 of 31

Here the servlet and the MyHtmlFiles directory are in the same position relative to the images directory. This means that you should write the link to the image in the servlet as you would in the html files in the MyHtmlFiles directory. <img src="../images/Duke.gif"> or <img src=" /images/Duke.gif"> How do you check for the existence of a cookie? Retrieving cookie data is a little awkward. You cannot ask for the cookie with a specific key. You must ask for all cookies and find the specific one you are interested in. And, it is possible that multiple cookies could have the same name, so just finding the first setting is not always sufficient. The following code finds the setting of a single-valued cookie: int sum = 0; Cookie theCookie = null; Cookie cookies[] = request.getCookies(); if (cookies != null) { for(int i=0, n=cookies.length; i < n; i++) { theCookie = cookies[i]; if (theCookie.getName().equals(SUM_KEY)) { try { sum = Integer.parseInt(theCookie.getValue()); } catch (NumberFormatException ignored) { sum = 0; } break; } } } How do I install Apache and Tomcat with SSL support? STeve Punte , from the Tomcat Users List, writes: The web site http://www.ccl.net/cca/software/UNIX/apache/index.shtml was great for me on getting SSL operational. Not for the faint of heart! Also, Jun Inamori has written a great tutorial walkthrough on compiling and installing Apache with Tomcat and JServ at http://www.oop-reserch.com/tomcat_3_1/. Is there a chat servlet out there? http://apache.wrox.co.uk/projsp/chap05/index.shtml#74 How can my servlet class which subclasses GenericServlet/HttpServlet provide an RMI service? Instead of letting your service subclass the java.rmi.server.UnicastRemoteObject class it is possible to make a call to the static method in the same class: exportObject(Remote). Thus you should let your class subclass GenericServlet/HttpServlet and implement a Remote interface. In the init(ServletContext) method your instance can export itself. A simple example follows (exception handling omitted) : public class MyServlet extends HttpServlet implements MyRemoteInterface { public void init(ServletContext ctx) { UnicastRemoteObject.exportObject(this); } // rest of code goes here... } Good luck! Is Tomcat 3.1 Beta stable enough to use in a production environment? No. By definition, the beta status says that that program should (only) be used for ("serious") testing. Of course, it's up to you whether or not you heed that warning. How do I configure the Tomcat server to allow access to servlets? If you're asking how to setup Tomcat to run servlets then you should probably start by reading the current version of the still nascent Tomcat User Guide. How do i delete a cookie set by a servlet? Get the cookie from the request object and use setMaxAge(0) and then add the cookie to the response object. When will a servlet engine send the HTTP response header? Is it immediately after getWriter/getOutputStream is called, or is it just before any call to write()? This is an implementation specific detail of the servlet engines. I.e., it depends. Of course, at the very best, once you've flushed content to the client, there's no way back. :-) Mohan

Servlets FAQ

Page 23 of 31

In the Java Servlet Specification v2.2, section 6.1, support has been added which gives the servlet developer a lot more information and at least some hope of portably being able to control the buffering. How do I connect Apache (1.3.12) to the Tomcat 3.x engine ? Check out the still nascent Tomcat Users Guide. How do I set init parameters in the servlet engine? It depends on the servlet engine. Each has its own type of config file in which you can set the names and values of init parameters; these get passed to the servlets (or JSPs) via the getInitParameter() call. For Tomcat and JSWDK, edit the conf/web.xml file. Please add information about other servlet engines as feedback to this FAQ. See this FAQ for information on passing an init param to a JSP. Can a servlet act as an HTTP client? Yes. Use the standard java.net.URL class, or "roll your own" using java.net.Socket. See the HTTP spec at W3C for more detail. Feedback to this FAQ has additional information about initiating an HTTP connection from Java. What are the advantages of using Servlets rather than CGIs? When a normal CGI script (or program) is executed, it is spawned in a separate process by the web server, and the output of that process becomes the resulting page that is sent back to the client. Each request to the web server will result in a new process beeing started. Starting a process will create some overhead, in performance and in memory usage. In servlets however, only one process is spawned, and that process contains the JVM. Each request will cause the JVM to create a new thread that will be responsible for creating the output that will be the result. Creating a thread requires much less resources to start up, both CPU and memory. This approach can make servlets much more efficient than even an optimized C program acting as a CGI, simply because of the much reduced overhead. However, there are upcoming standards around CGI that use the same approach with threads instead of processes, such as the Perl FastCGI module. So the above holds true for the comparision with a 'normal' CGI, not necessarily with all variants. There are of course other advantages. • Java is a well structured language suitable for larger systems. Many of the script languages used for CGI are formidable for small scripts and applications, but when larger systems are built, it is not uncommon to find that the code is a horror to maintain. It is probably easier to find a capable Java programmer than a Perl/CSH/PHP3/... programmer. This is a point not to be forgotten if you want someone else to be able to take over and/or understand your code.

Undoubtedly there are other advantages, but I stop here. I just want to add that: Using the correct technology is not as important as using the technology correctly. How can I get the version of the Servlet API that is being used by a servlet/JSP engine? The ServletContext interface includes methods getMajorVersion() and getMinorVersion() to tell you what version of the Servlet API is in use. What servlet engines support clustering? JRun 3.0 (Right now in RC1) will support clustering with an add-on. check http://www.allaire.com for info. Have JSP or Servlets anything similar to ASP's event "Session_OnStart"? The JRun product from Allaire adds a global.jsa file with events for session and application. What are the advantages and disadvantages of the different forms of session tracking (cookies, session objects, hidden fields, URL rewriting)? Here are the advantages and disadvantages I found with them: Technique Advantages Disadvantages 1. size and number of cookies stored are limited. 2. it stored as plain-text in a specific directory, 1. simple everyone can view and modify them. Personal 2. don't need to send data back to us, browser information is exposed. can participate in this task. 3. it won't work if the security level set too high in browser. 1. simple 2. No effect on security level setting in browsers. 1. the documents needs to embedded the data inside, waste bandwidth. e.g., if you have to conduct a webbased survey with multiple pages using hidden fields.

Cookies

Hidden Fields

Mohan

Servlets FAQ You have to embed the result from previous pages in the next page. 2. Everyone can see the embedded data by viewing the original source code. 3. If the user surfs to a different site, or to a static section of the same site, the state is lost. 1. URL is lengthy and the length of the URL is limited, 1. Every data is appended on the URL => easy can't store many information. to debug. 2. The URL contains data. If you send this URL to your 2. Works even if users disable cookies friends, they might see your information. Session usually use either cookies or URL rewriting (depends on security setting of browser) to make it function. Each user will have its own unique session ID to identify Session himself. The session data will be stored in the Objects : None :-) server and we can use the session ID to access these data. The session ID will be sent to user either cookies or URL Rewriting. Since the data are stored in server, the size of data is theoretically unlimited. Can I have multiple browser windows use different session IDs? No. Sessions are referenced using cookies, and cookies are set per-client, not per-window. URL Rewriting

Page 24 of 31

However, there's nothing keeping you from writing your own state management code, using URL rewriting, hidden fields, or the like, for use in parallel windows on the same machine. Why do GenericServlet and HttpServlet implement the Serializable interface? GenericServlet and HttpServlet implement the Serializable interface so that servlet engines can "hybernate" the servlet state when the servlet is not in use and reinstance it when needed or to duplicate servlet instances for better load balancing. I don't know if or how current servlet engines do this, and it could have serious implications, like breaking references to objects gotten in the init() method without the programmer knowing it. Programmers should be aware of this pitfall and implement servlets which are stateless as possible, delegating data store to Session objects or to the ServletContext. In general stateless servlets are better because they scale much better and are cleaner code. How do you manage sessions if the web servers are load balanced onto more than one server? Session management is automatic if the server supports load-balancing on more machines. The JavaWorld article What's New in Java Servlet API 2.2? clarifies on the subject in the paragraph Distributed Applications. The following is taken from that doc. Distributed Applications A few clarifications were also made in 2.2 with regards to distributed applications, in which application components can be spread across multiple back-end server machines. The specification dictates that, for an application marked as distributable in its deployment descriptor, there will be a single ServletContext instance per JVM. This means the context attributes cannot be used to share global information. Global information in a distributed app needs to be stored externally from the Web server, as is the case in database or EJB component. An application marked as distributable also has special rules for user sessions. Servers will use session affinity to efficiently manage user state across multiple back-end servers. This means that all requests that are part of a single session from a particular user are to be handled by only one JVM at a time. This in turn eliminates the need to constantly replicate session information across all the back-end servers. Responsibility for the session can be moved to another server between user requests, though in practical terms this is unlikely to occur frequently. Still, to enable the moving of a session, all objects placed into a session by servlets in a distributed application must implement Serializable. A Web server can throw an IllegalArgumentException if this condition is not met. Nondistributed apps, of course, can store any objects into the session. How does one choose between overriding the doGet(), doPost(), and service() methods? The differences between the doGet() and doPost() methods are that they are called in the HttpServlet that your servlet extends by its service() method when it recieves a GET or a POST request from a HTTP protocol request. A GET request is a request to get a resource from the server. This is the case of a browser requesting a web page. It is also possible to specify parameters in the request, but the length of the parameters on the whole is limited. This is the case of a form in a web page declared this way in html: <form method="GET"> or <form>. A POST request is a request to post (to send) form data to a resource on the server. This is the case of of a form in a web page declared this way in html: <form method="POST">. In this case the size of the parameters can be much greater. The GenericServlet has a service() method that gets called when a client request is made. This means that it gets called by Mohan

Servlets FAQ

Page 25 of 31

both incoming requests and the HTTP requests are given to the servlet as they are (you must do the parsing yourself). The HttpServlet instead has doGet() and doPost() methods that get called when a client request is GET or POST. This means that the parsing of the request is done by the servlet: you have the appropriate method called and have convenience methods to read the request parameters. NOTE: the doGet() and doPost() methods (as well as other HttpServlet methods) are called by the service() method. Concluding, if you must respond to GET or POST requests made by a HTTP protocol client (usually a browser) don't hesitate to extend HttpServlet and use its convenience methods. If you must respond to requests made by a client that is not using the HTTP protocol, you must use service(). What is the best way of implementing a web application that uses JSP, servlet and EJB technologies all together following a Model View Controller (MVC) architecture? Hmm, 'Best Way' is a bit rough - there are several 'good' ways, and the usual set of trade-offs between them. (I'm a consultant - I have to start any answer with "It depends...", otherwise they revoke my whiteboard privileges) The main thing you need to keep in mind as you design this sort of a system is that you want the interface into the EJB's to be rather narrow: in any flow, the ideal is to call one EJB method (hopefully on a stateless session bean), and let it make calls to entities on your behalf, then hand back the data you need to display. How you display it depends: you can either embed beans on your JSPs and let the beans make that hopefully-one EJB call, or you can post to a servlet, let that make the call, then forward to the JSP for display. The second of these is more flexible and gives you more leverage to hide, change, and enforce your site's structure. The first, however, will be easier for developers new to this web thing to follow. Essentially, I'm saying that Entity beans are your model, your controller is Session beans (maybe with a bit of help from servlets or beans), and your JSPs, beans and servlets are your View. One thing to note here: this discussion strongly implies that your EJBs are capable of externalizing their state as some number of very simple 'value objects' (not EJBs themselves, just something we can pass back and forth). These value objects are probably tuned tightly to a workflow, and will be produced by that session bean. This way the traffic between the EJB (server) and the JSP/Servlet (client) is tuned to what the client needs, while the transaction load on the server is minimized. How do I send a WML page as a response from a servlet? Sending WML is no different than sending back HTML. The only difference is you have to setup the MIME type in the response: response.setContentType("text/vnd.wap.wml"); Is Tomcat robust enough for production use? IMHO yes. We are presently running Tomcat (servlet & jsp requests) with Apache (graphics, perl, html) on 9 Solaris/Sparc servers servicing over 10 million servlet/jsp transactions per day. No known issues at this time! The site is Webhelp.com Why is my cookie is expiring before the time set using the Cookie.setMaxAge method? Chances are you have an "=" char in the value of your cookie. Make sure you URL encode the value of your cookie before setting it. How do servlets differ from RMI? What are the advantages and disadvantages of each technology? Servlets extend the server-side functionality of a website. Servlets communicate with other application(s) on that server (or any other server) and perform tasks above and beyond the "normal" static HTML document. A servlet can receive a request to get some information through EJB from one or more databases, then convert this data into a static HTML/WML page for the client to see, for example. Even if the servlet talks to many other applications all over the world to get this information, it still looks like it happened at that website. RMI (Remote Method Invocation) is just that - a way to invoke methods on remote machines. It is way for an application to talk to another remote machine and execute different methods, all the while appearing as if the action was being performed on the local machine. Servlets (or JSP) are mainly used for any web-related activity such as online banking, online grocery stores, stock trading, etc. With servlets, you need only to know the web address and the pages displayed to you take care of calling the different servlets (or actions within a servlet) for you. Using RMI, you must bind the RMI server to an IP and port, and the client who wishes to talk to the remote server must know this IP and port, unless of course you used some kind of in-between lookup utility, which you could do with (of all things) servlets. What are the main differences between Servlets and CGI? Servlets are effectively a Java version of CGI scripts, which are written in Perl, C, C++, UNIX shell scripts, etc. There are however, a few important differences. When a CGI program (or script) is invoked, what typically happens is that a new process is spawned to handle the request. This process is external to that of the webserver and as such, you have the overhead of creating a new process and context switching, etc. If you have many requests for a CGI script, then you can imagine the consequences! Of course, this is a Mohan

Servlets FAQ

Page 26 of 31

generalization and there are wrappers for CGI that allow them to run in the same process space as the webserver. I think ISAPI is/was one of these. Java Servlets on the other hand actually run inside the webserver (or Servlet engine). The developer writes the Servlet classes, compiles them and places them somewhere that the server can locate them. The first time a Servlet is requested, it is loaded into memory and cached. From then on, the same Servlet instance is used, with different requests being handled by different threads. Of course, being Java, the compiled Servlet classes can be moved from one Servlet compatible webserver to another very easily. CGI programs or scripts on the other hand may be platform dependent, need to be recompiled or even webserver dependent. Where can I find a method that returns a properly escaped HTML string from a given string of raw HTML? You can find that method in java.net.URLEncoder. ie: String Args = URLEncoder.encode("The raw data you want to encode"); Is there a problem with calling Response.sendRedirect() after Response.addCookie() ? Yes, there is a bug in Tomcat 3.1 (and possibly other servlet engines). To send a cookie through a redirect, you must set the headers manually. seanm@narus.com suggests: Cookie long_term = new Cookie(LONG_TERM_COOKIE_NAME, user_name); long_term.setMaxAge(60*60*24*4); long_term.setPath("/Blah"); response.addCookie(long_term); response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); response.setHeader("Location",REDIRECT_PAGE); Why does Tomcat fail with a java.lang.ClassNotFoundException: org/apache/tomcat/service/http/HttpConnectionHandler ? It's probably due to a bug in your JVM's Classloader. Try upgrading to JDK 1.2.2 or 1.3. What servlet code corresponds to the various "scope" values for the tag? The jsp:useBean tag is very powerful. It allows you to declare a variable using a single syntax, but produces code that (a) either initializes the variable, or locates it if it's already been initialized, and (b) stores it in one of a number of locations, depending on its scope. In order to share variables between JSPs and Servlets, you need to know how to create and to access variables from inside your servlet code. Following are examples which should help you understand how to do this. <jsp:useBean class="foo.Counter" scope="application" /> In this example, when the Counter bean is instantiated, it is placed within the servlet context, and can be accessed by any JSP or servlet that belongs to the application (i.e. belongs to the same servlet context). The servlet equivalent of the above useBean action is: foo.Counter counter = (foo.Counter)getServletContext().getAttribute("counter"); if (counter == null) { counter = new foo.Counter(); getServletContext().setAttribute("counter", counter); } <jsp:useBean id="counter" class="foo.Counter" scope="session" /> In this example, when the Counter bean is instantiated, it is placed within the current session, and can be accessed by any JSP or servlet during a subsequent request by the current user. The servlet equivalent of the above useBean action is: HttpSession session = request.getSession(true); foo.Counter counter = (foo.Counter)session.getValue("counter"); if (counter == null) { counter = new foo.Counter(); session.putValue("counter", counter); } <jsp:useBean id="counter" class="foo.Counter" scope="request" /> In this example, when the Counter bean is instantiated, it is placed within the current request object, and can be accessed by any JSP or servlet during a the same request; e.g., if a RequestDispatcher is used, or if or sends the request to another Mohan

Servlets FAQ servlet or JSP. The servlet equivalent of the above useBean action is: foo.Counter counter = (foo.Counter)request.getAttribute("counter"); if (counter == null) { counter = new foo.Counter(); request.setAttribute("counter", counter); } <jsp:useBean id="counter" class="foo.Counter" scope="page" />

Page 27 of 31

In this example the Counter bean is instantiated as a local variable inside the JSP method. It is impossible to share a page scope variable with another JSP or Servlet. The servlet equivalent of the above useBean action is: foo.Counter counter = new foo.Counter(); How can I support HTTPS (SSL) in a servlet? The servlet technology by design already supports https (SSL). However, the way this works is not through the servlet technology but through the Web Server. The web server controls whether information is done securely (https) versus non-securely (http). One way to force servlets to go down the https path is to define your web server to only allow secure connections when accessing servlets. In IIS this can be accomplished through the definition if ISAPI filters. The ISAPI filter can instruct the web server to route all requests that end with a pre-defined prefix to the servlet engine. The trick is to then define files, with the predefined extension, in the web servers directory. For example, if the servlet's name is MyServlet a file with the name MyServlet.xxx would be placed on the web server. All calls to this file would be routed to the servlet engine. And IIS would be used to force all calls to the MyServlet.xxx file to go through https. The JRun servlet engine has examples of how to do this documented on their web page. Can the security context be passed between a web container (servlets/jsp) and an EJB container ? When the servlet calls an EJB I want its identity to be that of the original web client authenticated with a certificate. The whole issue of propagation of authentication context from client to the EJB server is still evolving - both in terms of the specification as well as vendor offerings. According to the current Java 2 specification (page 224): "the container is the authentication boundary between callers and components hosted by the caller. For inbound calls it is the container's responsibility to make an authentic representation of the caller identity available to the component". The JAAS 1.0 specification extends the types of principals and credentials that can be associated with the client but it is also evolving. Thus given the container implementation that is required to drive this whole thing, the answer depends on your app vendor - some like Weblogic (WLE), Websphere provide security plug-ins/SDKs that can enable the propagation. Other vendors are close behind. Check your vendor plug-in. How can I cache the results of my servlet, so the next request doesn't have to go through all the calculation / database access / other time-consuming stuff all over again? Jason Hunter, author of the O'Reilly Servlets book, has written a nice little class called CacheHttpServlet. If your servlet subclasses CacheHttpServlet and overrides one method, the superclass takes care of caching the last response. Note that as written, it only caches one version; if you have multiple possible pages based on request parameters, it won't be as effective. Someone should probably extend this class to handle multiple pages. How can we use a servlet as a proxy for communications between two applets? Jim Garrett writes: One way to accomplish this is to have the applets communicate via TCP/IP sockets to the servlet. The servlet would then use a custom protocol to receive and push information between applets. However, this solution does have firewall problems if the system is to be used over and Internet verses an Intranet. Alex Chaffee adds: You could also have the applets use HTTP to communicate with the servlet, using the standard URLConnection classes as described in How can my applet communicate with my servlet?. This is more likely to get through the firewall, but it means that the second (receiver) applet must continually poll the servlet to check for new information. Jim Garrett continues: One other solution which works with simple data is to combine Java Applet technology with Java Scripts. Since an applet can communicate with Java Script, and Java Script can communicate with applets, it is possible to create an environment where JavaScript is used to pass information between applets. This solution works when the data being sent Mohan

Servlets FAQ between applets is text data. Douglas E Miller gives some source code examples: Protocol import java.net.*; import java.io.*; public class KnockKnockProtocol { private static final int WAITING = 0; private static final int SENTKNOCKKNOCK = 1; private static final int SENTCLUE = 2; private static final int ANOTHER = 3; private static final int NUMJOKES = 5; private int state = WAITING; private int currentJoke = 0; private String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" }; private String[] answers = { "Turnip the heat, it's cold in here!", "I didn't know you could yodel!", "Bless you!", "Is there an owl in here?", "Is there an echo in here?" }; public String processInput(String theInput) { String theOutput = null; if (state == WAITING) { theOutput = "Knock! Knock!"; state = SENTKNOCKKNOCK; } else if (state == SENTKNOCKKNOCK) { if (theInput.equalsIgnoreCase("Who's there?")) { theOutput = clues[currentJoke]; state = SENTCLUE; } else { theOutput = "You're supposed to say \"Who's there?\"! " + "Try again. Knock! Knock!"; } } else if (state == SENTCLUE) { if (theInput.equalsIgnoreCase(clues[currentJoke] + " who?")) { theOutput = answers[currentJoke] + " Want another? (y/n)"; state = ANOTHER; } else { theOutput = "You're supposed to say \"" + clues[currentJoke] + " who?\"" + "! Try again. Knock! Knock!"; state = SENTKNOCKKNOCK; } } else if (state == ANOTHER) { if (theInput.equalsIgnoreCase("y")) { theOutput = "Knock! Knock!"; if (currentJoke == (NUMJOKES - 1)) currentJoke = 0; else currentJoke++; state = SENTKNOCKKNOCK; } else { theOutput = "Bye."; state = WAITING; } } return theOutput;

Page 28 of 31

}

}

Mohan

Servlets FAQ

Page 29 of 31

Client public class KnockKnockClient { public static void main(String[] args) throws IOException { Socket kkSocket = null; PrintWriter out = null; BufferedReader in = null; try { kkSocket = new Socket("taranis", 4444); out = new PrintWriter(kkSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Don't know about host: taranis."); System.exit(1); } catch (IOException e) { System.err.println("Couldn't get I/O for the connection to: taranis."); System.exit(1); } BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); String fromServer; String fromUser; while ((fromServer = in.readLine()) != null) { System.out.println("Server: " + fromServer); if (fromServer.equals("Bye.")) break; fromUser = stdIn.readLine(); if (fromUser != null) { System.out.println("Client: " + fromUser); out.println(fromUser); }

}

}

}

out.close(); in.close(); stdIn.close(); kkSocket.close();

Server public class KnockKnockServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(4444); } catch (IOException e) { System.err.println("Could not listen on port: 4444."); System.exit(1); } Socket clientSocket = null; try { clientSocket = serverSocket.accept(); } catch (IOException e) {

Mohan

Servlets FAQ System.err.println("Accept failed."); System.exit(1);

Page 30 of 31

}

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader( clientSocket.getInputStream())); String inputLine, outputLine; KnockKnockProtocol kkp = new KnockKnockProtocol(); outputLine = kkp.processInput(null); out.println(outputLine); while ((inputLine = in.readLine()) != null) { outputLine = kkp.processInput(inputLine); out.println(outputLine); if (outputLine.equals("Bye.")) break; } out.close(); in.close(); clientSocket.close(); serverSocket.close();

}

}

[Of course, the KnockKnockServer isn't actually a servlet, which is kind of important for the sake of the example, but you can probably figure it out from here. -Alex] What is the difference between POST and GET methods? What about PUT? GET and POST basically allow information to be sent back to the webserver from a browser (or other HTTP client for that matter). Imagine that you have a form on a HTML page and clicking the "submit" button sends the data in the form back to the server, as "name=value" pairs. Choosing GET as the "method" will append all of the data to the URL and it will show up in the URL bar of your browser. The amount of information you can send back using a GET is restricted as URLs can only be 1024 characters. A POST on the other hand will (typically) send the information through a socket back to the webserver and it won't show up in the URL bar. You can send much more information to the server this way - and it's not restricted to textual data either. It is possible to send files and even binary data such as serialized Java objects! A PUT allows you to "put" (upload) a resource on to a webserver so that it be found under a specified URI. How can I design my servlet so that query results get displayed on several pages, like the results of a search engine? Use a Java Bean to store the entire result of the search that you have found. The servlet will then set a pointer to the first line to be displayed in the page and the number of lines to display, and force a display of the page. The Action in the form would point back to the servlet in the JSP page which would determine whether a next or previous button has been pressed and reset the pointer to previous pointer + number of lines and redisplay the page. The JSP page would have a scriplet to display data from the Java Bean from the start pointer set to the maximum number of lines with buttons to allow previous or next pages to be selected. These buttons would be displayed based on the page number (i.e. if first then don't display previous button). Is there an RPM for Tomcat? Yes, take a look at ftp://ftp.falsehope.com/home/gomez/jakarta/3.1/ by GOMEZ Henri . How do I upload a file using a Java client (not a browser) and HTTP POST? Many of the examples show how a HTML page can be constructed to select the file and do the POST, but I need to do it from a java client. [Note: the following example works, but it does not encode the POSTed file in the multipart/* format expected by servlets as described in How do I upload a file to my servlet?. Perhaps another Guru could submit some feedback ...? -Alex] Use the URLConnection class to upload a file to a web site and a servlet that understands how to read that file. At the client level public class HTTP_post { URL u; public static void main(String args[]) { String s=URLEncoder.encode("A Test string to send to a servlet");

Mohan

Servlets FAQ try { HTTP_post post = new HTTP_post(): post.u = new URL("http://myhost/servlet"); // Open the connection and prepare to POST URLConnection uc = u.openConnection(); uc.setDoOutput(true); uc.setDoInput(true); uc.setAllowUserInteraction(false); DataOutputStream dstream = new DataOutputStream(uc.getOutputStream()); // The POST line dstream.writebytes(s); dstream.close(); // Read Response DataInputStream dis = new DataInputStream(uc.getInputStream()); string nextline; while ( (nextline = dis.readline()) != null) { System.out.println(nextline); } dis.close();

Page 31 of 31

}

}

} catch (MalformedURLException e) { System.err.println("Not a URL I understand"); } catch (Exception e) { System.err.println(e); }

At Servlet end Perform a getInputStream to read the input and send the data to a file Example: DataInputStrean dis = new DataInputStream(request.getInputSteam()); String thedata=""; while (( String s - dis.readline()) != null) { thedata+=s; }

Mohan

Sign up to vote on this title
UsefulNot useful