Tuesday 26 June 2012

servlets interview questions and answers

Servlets Faqs-->1

1) Is it the "servlets" directory or the "servlet" directory?

For Java Web Server:
  • on the file system, it's "servlets"
c:\JavaWebServer1.1\servlets\DateServlet.class
  • in a URL path, it's "servlet"
http://www.stinky.com/servlet/DateServlet

2) 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);
        }

3) How do I ensure that my servlet is thread-safe?

This is actually a very complex issue. A few guidelines:
  1. The init() method is guaranteed to be called once per servlet instance, when the servlet is loaded. You don't have to worry about thread safety inside this method, since it is only called by a single thread, and the web server will wait until that thread exits before sending any more threads into your service() method.
  2. Every new client request generates (or allocates) a new thread; that thread calls the service() method of your servlet (which may in turn call doPost(), doGet() and so forth).
  3. Under most circumstances, there is only one instance of your servlet, no matter how many client requests are in process. That means that at any given moment, there may be many threads running inside the service() method of your solo instance, all sharing the same instance data and potentially stepping on each other's toes. This means that you should be careful to synchronize access to shared data (instance variables) using the synchronized keyword. (Note that the server will also allocate a new instance if you register the servlet with a new name and, e.g., new init parameters.)
  4. Note that you need not (and should not) synchronize on local data or parameters. And especially you shouldn't synchronize the service() method! (Or doPost(), doGet() et al.)
  5. A simple solution to synchronizing is to always synchronize on the servlet instance itself using "synchronized (this) { ... }". However, this can lead to performance bottlenecks; you're usually better off synchronizing on the data objects themselves.
  6. If you absolutely can't deal with synchronizing, you can declare that your servlet "implements SingleThreadModel". This empty interface tells the web server to only send one client request at a time into your servlet. From the JavaDoc: "If the target servlet is flagged with this interface, the servlet programmer is guaranteed that no two threads will execute concurrently the service method of that servlet. This guarantee is ensured by maintaining a pool of servlet instances for each such servlet, and dispatching each service call to a free servlet. In essence, if the servlet implements this interface, the servlet will be thread safe." Note that this is not an ideal solution, since performance may suffer (depending on the size of the instance pool), plus it's more difficult to share data across instances than within a single instance.
See also What's a better approach for enabling thread-safe servlets and JSPs? SingleThreadModel Interface or Synchronization?
  1. To share data across successive or concurrent requests, you can use either instance variables or class-static variables, or use Session Tracking.
  2. 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.
  3. 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.
4) What is the difference between URL encoding, URL rewriting, HTML escaping, and entity encoding?

URL Encoding is a process of transforming user input to a CGI form so it is fit for travel across the network -- basically, stripping spaces and punctuation and replacing with escape characters. URL Decoding is the reverse process. To perform these operations, call java.net.URLEncoder.encode() and java.net.URLDecoder.decode() (the latter was (finally!) added to JDK 1.2, aka Java 2).
Example: changing "We're #1!" into "We%27re+%231%21"
URL Rewriting is a technique for saving state information on the user's browser between page hits. It's sort of like cookies, only the information gets stored inside the URL, as an additional parameter. The HttpSession API, which is part of the Servlet API, sometimes uses URL Rewriting when cookies are unavailable.
Example: changing <A HREF="nextpage.html"> into
<A HREF="nextpage.html;$sessionid$=DSJFSDKFSLDFEEKOE"> (or whatever the actual syntax is; I forget offhand) (Unfortunately, the method in the Servlet API for doing URL rewriting for session management is called encodeURL(). Sigh...)
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) .

5) How do I upload a file to my servlet or JSP?

On the client side, the client's browser must support form-based upload. Most modern browsers do, but there's no guarantee. For example,

        <FORM ENCTYPE='multipart/form-data'  method='POST' action='/myservlet'>
           <INPUT TYPE='file' NAME='mptest'>
           <INPUT TYPE='submit' VALUE='upload'>
        </FORM>
The input type &quot;file&quot; 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 can use 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.
When the user clicks the "Upload" button, the client browser locates the local file and sends it using HTTP POST, encoded using the MIME-type multipart/form-data. When it reaches your servlet, your servlet must process the POST data in order to extract the encoded file. You can learn all about this format in RFC 1867.
Unfortunately, there is no method in the Servlet API to do this. Fortunately, there are a number of libraries available that do. Some of these assume that you will be writing the file to disk; others return the data as an InputStream.
  • Jason Hunter's MultipartRequest (available from http://www.servlets.com/)
  • Apache Jakarta Commons Upload (package org.apache.commons.upload) "makes it easy to add robust, high-performance, file upload capability to your servlets and web applications"
  • CParseRFC1867 (available from http://www.servletcentral.com/).
  • HttpMultiPartParser by Anil Hemrajani, at the isavvix Code Exchange
  • 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).
  • Jun Inamori has written a class called org.apache.tomcat.request.ParseMime which is available in the Tomcat CVS tree.
  • JSPSmart has a free set of JSP for doing file upload and download.
  • UploadBean by JavaZoom claims to handle most of the hassle of uploading for you, including writing to disk or memory.
  • There's an Upload Tag in dotJ
Once you process the form-data stream into the uploaded file, you can then either write it to disk, write it to a database, or process it as an InputStream, depending on your needs. See How can I access or create a file or folder in the current directory from inside a servlet? and other questions in the Servlets:Files Topic for information on writing files from a Servlet.
Please note that you can't access a file on the client system directly from a servlet; that would be a huge security hole. You have to ask the user for permission, and currently form-based upload is the only way to do that.

6) How does a servlet communicate with a JSP page?

The following code snippet shows how a servlet instantiates a bean and initializes it with FORM data posted by a browser. The bean is then placed into the request, and the call is then forwarded to the JSP page, Bean1.jsp, by means of a request dispatcher for downstream processing.

        public void doPost (HttpServletRequest request,
                       HttpServletResponse response) {

           try {
             govi.FormBean f = new govi.FormBean();
             String id = request.getParameter("id");
             f.setName(request.getParameter("name"));
             f.setAddr(request.getParameter("addr"));
             f.setAge(request.getParameter("age"));
                //use the id to compute
                //additional bean properties like info
               //maybe perform a db query, etc.
                // . . .
                f.setPersonalizationInfo(info);
             request.setAttribute("fBean",f);
             getServletConfig().getServletContext().getRequestDispatcher
                       ("/jsp/Bean1.jsp").forward(request, response);
           } catch (Exception ex) {
             . . .
           }
        }
The JSP page Bean1.jsp can then process fBean, after first extracting it from the default request scope via the useBean action.

        <jsp:useBean id="fBean" class="govi.FormBean" scope="request"/>
        <jsp:getProperty name="fBean" property="name" />
        <jsp:getProperty name="fBean" property="addr" />
        <jsp:getProperty name="fBean" property="age" />
        <jsp:getProperty name="fBean" property="personalizationInfo" />

7) 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 usage is non-deterministic, it may not help much even if you did add more memory and increased the size of the instance pool.

8) 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.

9) 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 do 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.

10) How do I call one servlet from another servlet?

[ Short answer: there are several ways to do this, including
  • use a RequestDispatcher
  • use a URLConnection or HTTPClient
  • send a redirect
  • call getServletContext().getServlet(name) (deprecated, doesn't work in 2.1+)
- Alex ]

It depends on what you mean by "call" and what it is you seek to do and why you seek to do it.
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.


0 comments:

Post a Comment