Clouds
Home

J2EE Overview

J2EE Servlet 1

J2EE Servlet 2

J2EE JSP

J2EE JDBC

J2EE JNDI LDAP

J2EE RMI

J2EE EJB

J2EE JMS

J2EE XML

J2EE STRUTS

J2EE SERVERS

J2EE Best Practices

J2EE Logging

J2EE Testing

J2EE Deployment

J2EE Development Process

Servlet Interview Questions - Part 2


How can you invoke a JSP error page from a controller servlet ?

The following code demonstrates how an exception from a servlet can be passed to an error JSP page.

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    try {
      //doSomething
    } catch(Exception ex) {
      req.setAttribute("javax.servlet.ex",ex);//store the exception as a request attribute.
      ServletConfig sConfig = getServletConfig();
      ServletContext sContext = sConfig.getServletContext();
      sContext.getRequestDispatcher("/jsp/ErrorPage.jsp").forward(req, resp);// forward the
      //request with the exception stored as an attribute to the "ErrorPage.jsp".
      ex.printStackTrace();
    }
}


What are servlet lifecycle events ?

Servlet lifecycle events work like the Swing events. Any listener interested in observing the ServletContext lifecycle can implement the ServletContextListener interface and in the ServletContext attribute lifecycle can implement the ServletContextAttributesListener interface. The session listener model is similar to the ServletContext listener model (Refer Servlet spec 2.3 or later). ServletContext's and Sessionís listener objects are notified when servlet contexts and sessions are initialized and destroyed, as well as when attributes are added or removed from a context or session.
For example: You can declare a listener in the web.xml deployment descriptor as follows:

<listener>
    <listener-class>com.MyJDBCConnectionManager </listener-class>
</listener>


You can create the listener class as shown below:

public class MyJDBCConnectionManager implements ServletContextListener {
    public void contextInitialized(ServletContextEvent event) { Connection con = // create a connection
    event.getServletContext().setAttribute("con", con);
    }
public void contextDestroyed(ServletContextEvent e) {
    Connection con = (Connection) e.getServletContext().getAttribute("con");
    try { con.close(); } catch (SQLException ignored) { } // close connection
    }
}


The server creates an instance of the listener class to receive events and uses introspection to determine what listener interface (or interfaces) the class implements.

What is the difference between HttpServlet and GenericServlet?

GenericServlet

  • A GenericServlet has a service() method to handle requests.
  • Protocol independent. GenericServlet is for servlets that might not use HTTP (for example FTP service).

HttpServlet

  • The HttpServlet extends GenericServlet and adds support for HTTP protocol based methods like doGet(), doPost(), doHead() etc. All client requests are handled through the service() method. The service method dispatches the request to an appropriate method like doGet(), doPost() etc to handle that request. HttpServlet also has methods like doHead(), doPut(), doOptions(), doDelete(), and doTrace().
  • Protocol dependent (i.e. HTTP).

    How do you make a Servlet thread safe ? What do you need to be concerned about with storing data in Servlet instance fields?

    Servlet life cycle creates a single instance of each servlet and creates multiple threads to handle the service() method. The multithreading aids efficiency but the servlet code must be coded in a thread safe manner. The shared resources (e.g. instance variables, utility or helper objects etc) should be appropriately synchronized or should only use variables in a read-only manner. There are situations where synchronizing will not give you the expected results and to achieve the expected results you should store your values in a user session or store them as a hidden field values. Having large chunks of code in synchronized blocks in your service or doPost() methods can adversely affect performance and makes the code more complex.
    Alternatively it is possible to have a single threaded model of a servlet by implementing the marker or null interface javax.servlet.SingleThreadedModel.
    The container will use one of the following approaches to ensure thread safety:
    • Instance pooling where container maintains a pool of servlets.
    • Sequential processing where new requests will wait while the current request is being processed.

    Best practice:

    • It is best practice to use multi-threading and stay away from the single threaded model of the servlet unless otherwise there is a compelling reason for it. Shared resources can be synchronized, used in readonly manner, or shared values can be stored in a session, as hidden fields or in database table. The single threaded model can adversely affect performance and hence has been deprecated in the servlet specification 2.4.
    • Threads share the heap and have their own stack space (i.e. each thread has its own stack). This is how one threadís invocation of a method (doGet(), doPost()) and its local variables (e.g. int y) are kept thread safe from other threads. But the heap (e.g. int x ) is not thread-safe and must be synchronized for thread safety or stored in an HTTP session or stored as a hidden field. The variable "CONSTANT" is a read only immutable field since it is marked as final and hence thread-safe.

    How do you get your servlet to stop timing out on a really long database query ?

    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.

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

    Solution 2: J2EE Solution: Instead of spawning your own threads within your Servlet, you could use JMS (Java Messaging Service). This involves following steps:
    • 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 <META> tag discussed above or JavaScript. Both these Servlets should send the <META> tag with their responses until final display of the query results.
    • RequestingServlet places the query on the "request" queue using JMS.
    • 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.
    • DisplayingServlet checks the "reply" queue for the query results using JMS (use javax.jms.QueueReceiver & javax.jms.ObjectMessage) every few seconds via <META> 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.

    What is pre-initialization of a Servlet ?

    By default the container does not initialize the servlets as soon as it starts up. It initializes a servlet when it receives a request for the first time for that servlet. This is called lazy loading. The servlet deployment descriptor (web.xml) defines the <load-on-startup> element, which can be configured to make the servlet container load and initialize the servlet as soon as it starts up. The process of loading a servlet before any request comes in is called pre-loading or pre-initializing a servlet. We can also specify the order in which the servlets are initialized.
    <load-on-startup>2</load-on-startup>

    What is a RequestDispatcher ? What object do you use to forward a request ?

    A Servlet can obtain its RequestDispatcher object from its ServletContext.

    //...inside the doGet() method
    ServletContext sc = getServletContext();
    RequestDispatcher rd = sc.getRequestDispatcher("/nextServlet");//relative path of the resource
    //forwards the control to another servlet or JSP to generate response. This method allows one
    //servlet to do preliminary processing of a request and another resource to generate the
    //response.
    rd.forward(request,response);
    // or includes the content of the resource such as Servlet, JSP, HTML, Images etc into the
    // calling Servletís response.
    rd.include(request, response);

    What is the difference between the getRequestDispatcher(String path) method of "ServletRequest" interface and ServletContext interface?

    javax.servlet.ServletRequestgetRequestDispatcher(String path)

    Accepts path parameter of the servlet or JSP to be included or forwarded relative to the request of the calling servlet. If the path begins with a "/" then it is interpreted as relative to current context root.

    javax.servlet.ServletContextgetRequestDispatcher(String path)

    Does not accept relative paths and all path must start with a "/" and are interpreted as relative to current context root.

    What are the considerations for servlet clustering ?

    The clustering promotes high availability and scalability. The considerations for servlet clustering are:
    • 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().

    How to perform I/O operations in a Servlet/JSP ?

    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 <init-param> 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).

    //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.

    //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());


    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?

    Files can be downloaded from a web application by using the right combination of headers.

    //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);


    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 ?

    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/formdata" and the POST method in the
    tag as shown below:

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

    If an object is stored in a session and subsequently you change the state of the object, will this state change replicated to all the other distributed sessions in the cluster ?

    No. Session replication is the term that is used when your current service state is being replicated across multiple application instances. Session replication occurs when we replicate the information (i.e. session attributes) that are stored in your HttpSession. The container propagates the changes only when you call the setAttribute("") method. So mutating the objects in a session and then by-passing the setAttribute(....) will not replicate the state change.
    Example: If you have an ArrayList in the session representing shopping cart objects and if you just call getAttribute("") to retrieve the ArrayList and then add or change something without calling the setAttribute("") then the container may not know that you have added or changed something in the ArrayList. So the session will not be replicated.

    What is a filter, and how does it work ?

    A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses but typically do not themselves create responses. Filters can also be used to transform the response from the Servlet or JSP before sending it back to client. Filters improve reusability by placing recurring tasks in the filter as a reusable unit. A good way to think of Servlet filters is as a chain of steps that a request and response must go through before reaching a Servlet, JSP, or static resource such as an HTML page in a Web application.
    The filters can be used for caching and compressing content, logging and auditing, image conversions (scaling up or down etc), authenticating incoming requests, XSL transformation of XML content, localization of the request and the response, site hit count etc.
    The filters are configured through the web.xml file as follows:

    <web-app>
      <filter>
        <filter-name>HitCounterFilter</filter-name>
        <filter-class>myPkg.HitCounterFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>HitCounterFilter</filter-name>
        <url-pattern>/usersection/*</url-pattern>
      </filter-mapping>
      ...
    </web-app>


    The HitCounterFilter will intercept the requests from the URL pattern /usersection followed by any resource name.

    Explain declarative security for Web applications ?

    Servlet containers implement declarative security. The administration is done through the deployment descriptor web.xml file. With declarative security the Servlets and JSP pages will be free from any security aware code.
    You can protect your URLs through web.xml as shown below:

    <web-app>
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>PrivateAndSensitive</web-resource-name>
          <url-pattern>/private/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
          <role-name>executive</role-name>
          <role-name>admin</role-name>
        </auth-constraint>
      </security-constraint>
      <!-- form based authorization -->
      <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
        <form-login-page>/login.jsp</form-login-page>
        <form-error-page>/error.jsp</form-error-page>
        </form-login-config>
      </login-config>
    </web-app>


    The user will be prompted for the configured login.jsp when restricted resources are accessed. The container also keeps track of which users have been previously authenticated.
    Benefits: Very little coding is required and developers can concentrate on the application they are building and system administrators can administer the security settings without or with minimal developer intervention. Letís look at a sample programmatic security in a Web module like a servlet:

    User user = new User();
    Principal principal = request.getUserPrincipal();
    if (request.isUserInRole("boss"))
    user.setRole(user.BOSS_ROLE);


    Explain the Front Controller design pattern or explain J2EE design patterns ?

    Problem: A J2EE system requires a centralized access point for HTTP request handling to support the integration of system services like security, data validation etc, content retrieval, view management, and dispatching. When the user accesses the view directly without going through a centralized mechanism, two problems may occur:
    • Each view is required to provide its own system services often resulting in duplicate code.
    • View navigation is left to the views. This may result in shared code for view content and view navigation.
    • Distributed control is more difficult to maintain, since changes will often need to be made in numerous places.
    Solution: Generally you write specific servlets for specific request handling. These servlets are responsible for data validation, error handling, invoking business services and finally forwarding the request to a specific JSP view to display the results to the user. The Front Controller suggests that we only have one Servlet (instead of having specific Servlet for each specific request) centralizing the handling of all the requests and delegating the functions like validation, invoking business services etc to a command or a helper component. For example Struts framework uses the command design pattern to delegate the business services to an action class.
    Benefits
    • Avoid duplicating the control logic like security check, flow control etc.
    • Apply the common logic, which is shared by multiple requests in the Front controller.
    • Separate the system processing logic from the view processing logic.
    • Provides a controlled and centralized access point for your system.


    JSP Interview Questions >>>




    Home Clouds