Java Servlet Interview question & answer

Q. How do you get your servlet to stop timing out on a really long database query?
A. There are situations despite how much database tuning effort you put into a project, there might be complex queries or a batch process initiated via a Servlet, which might take several minutes to execute. The issue is that if you call a long query from a Servlet or JSP, the browser may time out before the call completes. When this happens, the user will not see the results of their request. There are proprietary solutions to this problem like asynchronous servlets in WebLogic, Async Beans in WebSphere etc but you need a solution that is portable. Let us look at portable solutions to this issue.


Solution 1: Client-pull or client-refresh (aka server polling): You can use the tag for polling the server. This tag tells the client it must refresh the page after a number of seconds. 

?
1
<META http-equiv=”Refresh” content=”10; url=”newPage.html” />


Once you can have the browser poll your Servlet on a regular basis to re-fetch a page, then your servlet can check for a value of a variable say in a HttpSession to determine if the page returned will have the results expected by the user or resend the tag with a “Please wait …” message and retry fetching the page again later.

Solution 2: JEE Solution: Instead of spawning your own threads within your Servlet, you could use JMS (Java Messaging Service). This involves following steps:

  1. You need to have two servlets, a RequestingServlet and a DisplayingServlet. The initial client request is sent to the RequestingServlet. Both the RequestingServlet and DisplayingServlet polled by the browser via tag discussed above or JavaScript. Both these Servlets should send the tag with their responses until final display of the query results.
  2. RequestingServlet places the query on the “request” queue using JMS.
  3. You need to have a MessageDrivenBean (aka MDB) say QueryProcessorMDB, which dequeues the query from the “request” queue and performs the long-running database operation. On completion of processing long-running database operation, the QueryProcessorMDB returns the query results to the “reply” queue (use javax.jms.QueueSender & javax.jms.ObjectMessage). Note: MDBs are invoked asynchronously on arrival of messages in the queue.
  4. DisplayingServlet checks the “reply” queue for the query results using JMS (use javax.jms.QueueReceiver & javax.jms.ObjectMessage) every few seconds via tag described above or a JavaScript.

Advantages: Firstly, implementing your long-running database operation to be invoked from onMessage( ) method of your QueryProcessorMDB decouples your application whereby if a database failure occurs, the request query message will be placed back in the “request” queue and retried again later. Secondly MDBs can be clustered (with or without additional JVMs) to listen on the same “request” queue. This means cluster of MDBs will be balancing the load of processing long running database operations. This can improve the throughput due to increased processing power.


Q. What is the difference between forwarding a request and redirecting a request? 
A. Both methods send you to a new resource like Servlet, JSP, etc



Forward:
  • Forward action takes place within the server without the knowledge of the browser. Accepts relative path to the servlet or context root.
  • No extra network trip.

Redirect:
  • Sends a header back to the browser, which contains the name of the resource to be redirected to. The browser will make a fresh request from this header information. Need to provide absolute URL path.
  • This has an overhead of extra remote trip but has the advantage of being able to refer to any resource on the same or different domain and also allows book marking of the page.
Q. What are the considerations for servlet clustering? 
A. 

  • Objects stored in a session should be serializable to support in-memory replication of sessions. Also consider the overhead of serializing very large objects. Test the performance to make sure it is acceptable.
  • Design for idempotence. Failure of a request or impatient users clicking again can result in duplicate requests being submitted. So the Servlets should be able to tolerate duplicate requests.
  • Avoid using instance and static variables in read and write mode because different instances may exist on different JVMs. Any state should be held in an external resource such as a database. 
  • Avoid storing values in a ServletContext. A ServletContext is not serializable and also the different instances may exist in different JVMs.
  • Avoid using java.io.* because the files may not exist on all backend machines. Instead use getResourceAsStream().

Q. How do you perform I/O operations in a Servlet/JSP? 
A. 

Problem: Since web applications are deployed as WAR files on the application server’s web container, the full path and relative paths to these files vary for each server. 

Solution -1: You can configure the file paths in web.xml using tags and retrieve file paths in your Servlets/JSPs. But this technique requires changes to the web.xml deployment descriptor file, to point to the correct path.


Solution -2: You can overcome these configuration issues by using the features of java.lang.ClassLoader and javax.servlet.ServletContext classes. There are various ways of reading a file using the ServletContext API methods such as getResource(String resource),getResourceAsStream(String resource), getResourcePaths(String path) and getRealPath(String path). The getRealPath(String path) method translates virtual URL into real path.

?
1
2
//Get the file “products.xml” under the WEB-INF folder of  your application as inputstream
InputStream is = config.getServletContext().getResourceAsStream(“/products.xml”);

Alternatively you can use the APIs from ClassLoader as follows. The file “products.xml” should be placed under WEB-INF/classes directory where all web application classes reside. 

?
1
2
3
4
5
6
7
//Get the URL for the file and create a stream explicitly
URL url = config.getServletContext().getResource(“/products.xml”);
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream));
                        OR
//use the context class loader
URL url  = Thread.currentThread().getContextClassLoader().getResource(“products-out.xml”);
BufferedWriter bw = new BufferedWriter(new FileWriter(url.getFile());


Q. How do you send a file to a browser from your web application? I.e. how do you download a file from your web application? 
A. Files can be downloaded from a web application by using the right combination of headers.

?
1
2
3
4
//set the header to a non-standard value for attachments to be saved by the browser with the //Save-As dialog so that it is unrecognized by the browsers because often browsers try to do //something special when they recognize the content-type.
response.setContentType(“application/x-download”);
//use Content-Disposition “attachment” to invoke “Save As” dialog and “inline” for displaying //the file content on the browser without invoking the “Save As” dialog.
response.setHeader(“Content-disposition”, “attachment;filename=” + fileName);


Q. How do you send a file from a browser to your web application? i.e. How do you upload a file to your web application? 
A. There are better and more secured ways to upload your files instead of using using web. For example FTP, secure FTP etc. But if you need to do it via your web application then your default encoding and GET methods are not suitable for file upload and a form containing file input fields must specify the encoding type “multipart/form-data” and the POST method in the 
tag as shown below:

?
1
2
3
4
<form enctype=”multipart/form-data” method=”POST”  action=”/MyServlet”>
     <input type=”file” name=”products” />
     <input type=”submit” name=”Upload” value=”upload” />
</form>   

When the user clicks the “Upload” button, the client browser locates the local file and sends it to the server using HTTP POST. When it reaches your server, your implementing servlet should process the POST data in order to extract the encoded file. Unfortunately, application servers implementing the Servlet and JSP specifications are not required to handle the multipart/form-data encoding. Fortunately there are number of libraries available such as Apache Commons File Upload, which is a small Java package that lets you obtain the content of the uploaded file from the encoded form data. The API of this package is flexible enough to keep small files in memory while large files are stored on disk in a “temp” directory. You can specify a size threshold to determine when to keep in memory and when to write to disk.

Comments

Popular posts from this blog

SQL Tutorial with HSQLDB

Hibernate tutorial with HSQLDB

Java Interview Questions & Answers: user defined key class