Skip to main content

Quick Reference to JAVA Servlets


I am writing these quick reference blogs for those who wants to brushup the ideas of each topic. This one will lead you through the basic concepts of JAVA Servlets.

How this quick reference guideline is different from the numerous other docs available ?  ,  please read on to get an idea :

Servlet Lifecycle :
  1. The container will identify the servlet based on the URL
  2. Servlet class loading
  3. Servlet instantaition
  4. Call init method
  5. Create a servlet thread for the current request.
  6. Before calling service(), will create the request and response objects
  7. Call service method
  8. Service method will identify whether to call doGet or doPost and call it
  9. Call destroy method

Different servlet objects :
  1. A sinlge servlet instance per JVM ( except for SingleTheadModel)
  2. A sinlge HttpSession per web application ( session activation and passivation)
  3. A sinlge ServletContext per JVM
  4. A sinlge ServletConfig per servlet
  5. A sinlge ServletRequest per servlet request

Important Servlet rq and rs methods :

javax.servlet.Servlet<<Interface>>
      <-- javax.servlet.GenericServlet
                <-- javax.servlet.HttpServlet

javax.servlet.ServletRequest<<Interface>>
        <-- javax.servlet.HttpServletRequest<<Interface>>

getParameter      getCookies        getRequestDispatcher
getParameterValues         getHeader             getSession           getMethod
getParameterNames               getIntHeader           getAttribute
getRemotePort --> remote to servlet is client. So this is client port.
getServerPort --> port to which request send ( eg:8080)
getLocalPort --> port for each thread to handle request

javax.servlet.ServletResponse<<Interface>>
      <-- javax.servlet.HttpServletResponse<<Interface>

setContentType            sendRedirect             setHeader
addCookie      encodeURL         addHeader
setIntHeader
getWriter      -->   PrintWriter  --> .print method
getOutputStream --> ServletOutputStream --> .write method


Simple Servlet class to get one parameter and a colection of parameters :

public class ServletOne extends HttpServlet{
    public void doGet(HttpServletRequest request,HttpServletResponse response)
                                                                       throws IOException, ServletException {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            String userName = request.getParameter("userName");
            String[] paramValues = request.getParameterValues("userNames");
            Enumeration parameterNames = request.getParameterNames();
            while(parameterNames.hasMoreElements()){
                    out.println("<br>request.parameterNames="+parameterNames.nextElement());
            }
            out.print("<br>request.getRemotePort()="+request.getRemotePort());
     }
}


General purpose of Servlet methods and objects :

public void init() --> usually to handle the ServletConfig.
public void destroy () --> commonly used for activities like close DB connections opened by the servlet.
ServletContext.InitParameter --> like database lookup name, EJB bean JNDI names
ServletContext.attribute --> like databaseConnection, concurrentUsers
HttpSession.attribute --> like shopping cart

Sample web.xml :

<web-app>

   <context-param>
       <param-name>bankURL</param-name>
       <param-value>www.myBank.com</param-value>
   </context-param>

   <servlet>
        <servlet-name>SampleServlet</servlet-name>
        <servlet-class>jspAndServlet.SampleServlet</servlet-class>
        <init-param>
                 <param-name>bankName</param-name>
                 <param-value>MyBank</param-value>
         </init-param>
   </servlet>

   <servlet-mapping>
         <servlet-name>SampleServlet</servlet-name>
         <url-pattern>/Serv1</url-pattern> --> possible to use wildcards
   </servlet-mapping>

   <session-config>
          <session-timeout>5</session-timeout>
    </session-config>

    <listener>
          <listener-class>listeners.ContextListener</listener-class>
    </listener>

    <welcome-file-list>
           <welcome-file>TestLogIn.html</welcome-file>
           <welcome-file>index.html</welcome-file>
     </welcome-file-list>

</web-app>


Servlet and RequestDispatcher :

RequestDispatcher rd = request.getRequestDispatcher("FirstJSP.jsp");   --> Relative or absolute path
rd.forward(request,response);

or

RequestDispatcher rd = getServletContext().getRequestDispatcher("FirstJSP.jsp");  --> Absolute path
rd.forward(request,response);

  • When we use "rd.include", control is retained by the calling resource.
  • When we use "rd.include", not full HttpServletResponse functionality is passed to the called resource.
  • Remember that you cannot forward the request if you have already committed a reponse like "out.print" or "os.flush"
  • To pass some data to JSP you can use any of HttpServletRequest or HttpSession or ServletContext objects

Servlet and HttpSession

Http is a stateless protocol. To get session we can use javax.servlet.http.HttpSession
The HttpSession interface is used with cookie and URL rewriting technology.

header send in response --> Set-Cookie:JSESSIONID=0AABB2345ED2
header send in request --> Cookie:JSESSIONID=0AABB2345ED2
  •    HttpSession session = request.getSesion();
  •    session.isNew()
  •    request.getSession(false) --> only already created session
  •    session.getId();
  •    session.getCreationTime();
  •    session.getLastAccessedTime();
  •    String userName = (String)session.getAttribute("userName");
  •    session.setAttribute("userName",request.getParameter("userName")); --> Cannot store primitive data types
  •    session.setMaxInactiveInterval(int interval);
  •    int interval = session.getMaxInactiveInterval();
  •    session.invalidate();
<session-config>
    <session-timeout>-1</session-timeout> --> will never expire
</session-config>

response.encodeURL("/BeerTest.do"); --> URL rewriting -->possible only with dynamically generated urls
response.encodeRedirectURL("/BeerTest.do");

Cookie cookie = new Cookie(userName,password);
cookie.setMaxAge(10*60);
response.addCookie(cookie);

Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies){
     String cookieName = cookie.getName();
     String cookieValue = cookie.getValue();
}

Servlet and Thread safety

Web components share information with other web components using objects that are maintained as attributes of four types of scope object
  • web context --> ServletContext
  • session --> HttpSession
  • request --> ServletRequest
  • page --> PageContext

1. You can ensure that each request works independently and doesn't access the servlet instance concurrently by implementing SingleThreadModel

      public class myServlet extends HttpServlet implements SingleThreadModel
      <%@ page isThreadSafe="true" %> --> The default value of the isThreadSafe attribute is "true".
                                                               --> Will not implement SingleThreadModel.

2. You can allow concurrent access while protecting the shared data in the same way as you do in other multithreaded Java applications. For high-traffic servlets, you should use explicit synchronized blocks rather than implementing the SingleThreadModel interface like
      synchronized(getServletContext()){ ... } or
      synchronized(session){ ... }

Only local variables and request parameters are thread safe.


Servlet and Filter

Filters are commonly used for :
  • authentication
  • localization
  • encryption
  • data compression
  • caching
  • logging --> given below
javax.servlet.Filter ---> init(), doFilter(), destroy()
javax.servlet.FilterChain

      public void init(FilterConfig config)
      public void doFilter(ServletRequest request, --> Please note that this is not HttpServletRequest
                                    ServletResponse response,
                                    FilterChain chain) throws IOException,ServletException

<filter>
     <filter-name>myFilter</filter-name>
     <filter-class>jspAndServlet.filter.CompressionFilter</filter-class>
      <init-param>
          <param-name>enableCompression</param-name>
          <param-value>true</param-value>
       </init-param>
</filter>

<filter-mapping>
     <filter-name>myFilter</filter-name>
      <url-pattern>/*</url-pattern>
</filter-mapping>

or

<filter-mapping>
      <filter-name>myFilter</filter-name>
      <servlet-name>SampleServlet</servlet-name>
</filter-mapping>

or

<filter-mapping>
       <filter-name>myFilter</filter-name>
       <url-pattern>/*</url-pattern>
       <dispatcher>REQUEST</dispatcher> or INCLUDE or FORWARD or ERROR
</filter-mapping>
                     --> from 2.4 version onwards   --> REQUEST is the default value --> All/any of thesre can be included

Container's rule for ordering the filters:
        1. All filters with "<url-pattern>" is taken in the order in which they are declared in DD.
        2. All filters with "<servlet-name>" is taken in the order in which they are declared in DD.

FilterChain.doFilter() --> Will invoke the next filter.
String filterName = filterConfig.getFilterName();

Logging using the filter:

     ServletContext context = filterConfig.getServletContext();
     context.log(new Date() + ": " + "Access to: " + req.getRequestURL()
                       + " requested by: " + req.getRemoteHost()
                       + ". (Reported by " + filterConfig.getFilterName() + ".)");

Compression using the filter:
   
     It can be used after the FilterChain.doFilter() call
Eg:
        public void doFilter(request,response,chain) {
                     //request handling
                     chain.doFilter()
                     //response handling --> compression.
        }

     Issue --> After the call "chain.doFilter()", response will already be flushed to client from servlet.
     Solution --> Create a new instance of "response" and copy all values to it and pass it.
             Issue --> The "response" has n values to copy --> need to code all ?
             Solution --> use Wrappers

                              ServletRequestWrapper               ServletResponseWrapper
                              HttpServletRequestWrapper        HttpServletResponseWrappers

Servlet and Listener

Use of Listener:   If you wanted to keep a count of the total number of users on a system, you could update a global userNumber variable upon receiving each session creation event(sessionCreated). Similarly contextInitialized can be used to create a connection common to all the servlets.

        <listener>
               <listener-class>listeners.ContextListener</listener-class>
        </listener>

  Changes that trigger events -->
          1. Initialization and destruction of servletContext.
          2. Initialization and destruction of ServletRequest.
          3. Initialization and destruction of session objects.
          4. Addition/Alteration/Removal of attributes associated with servletContext, ServletRequest or session objects.

java.util.EventListener                                         ---> java.util.EventObject

javax.servlet.ServletContextListener                    ---> javax.servlet.ServletContextEvent
contextInitialized getServletContext
contextDestroyed

javax.servlet.ServletContextAttributeListener      ---> javax.servlet.ServletContextAttributeEvent
attributeAdded                                                           getName
attributeRemoved                                                       getValue --> OLD value
attributeReplaced                                                       getServletContext

javax.servlet.ServletRequestListener                   ---> javax.servlet.ServletRequestEvent
requestInitialized                                                        getServletContext
requestDestroyed

javax.servlet.ServletRequestAttributeListener      ---> javax.servlet.ServletRequestAttributeEvent
attributeAdded                                                           getName
attributeRemoved                                                       getValue
attributeReplaced                                                       getServletContext

javax.servlet.HttpSessionListener                        ---> javax.servlet.HttpSessionEvent
sessionCreated                                                           getSession
sessionDestroyed

javax.servlet.HttpSessionAttributeListener          ---> javax.servlet.HttpSessionBindingEvent
attributeAdded                                                          getName
attributeRemoved                                                      getValue --> OLD value
attributeReplaced                                                      getSession

javax.servlet.HttpSessionBindingListener            ---> javax.servlet.HttpSessionBindingEvent
valueBound                                                               getName
valueUnbound                                                           getValue
(no need to configure this in DD)                                getSession

javax.servlet.HttpSessionActivationListener       --->  javax.servlet.HttpSessionEvent
sessionDidActivate                                                    getSession
sessionWillPassivate

HttpSessionBindingEvent extends HttpSessionEvent


Simpe Tips in servlet :
  1. WEB-INF --> The folder name should be in capital letter to work with Tomcat5.
  2. <form action="/urlOne" > --> If you have a folder like "Tomcat 5.5\webapps\test\urlOne", this will not work as this is an absolute path, this will search for "webapps/urlOne" and you have "webapps/test/urlOne". So need to use <form action="urlOne"> to get "webapps/test/urlOne".
  3. You can overrride the init() method and do the one time operations like create a DB connection.
  4. War files make it easy to transfer the web applications from one server to another.


Comments

Popular posts from this blog

ATG Search troubleshooting tips

In this blog, I have listed some basic ATG Search troubleshooting tips in some general scenarios. 1. If the index did not deploy, consider the following possible causes : Is the DeployShare property configured @ /atg/search/routing/LaunchingService component ?  Is enough space available @ deployment share box for the index ?  Are the RMI ports configured correctly in the RoutingSystemService component ?  If the search engine application is running in a separate box, this application is invoked through a RemoteLauncher running in these boxes. Check whether these RemoteLaunchers are running in these boxes ? 2. If you have trouble in launching one or more search engines, try the following remedies: If the Search engine is standalone, set the /atg/search/routing/LaunchingService component’s engineDir property to the absolute path of the Search engine directory.  3. Search unavailable in the estore page, even when the SearchEngine is in "Running" st...

Search Facets - how to create a new search facets in ATG Search

A Facet is a search refinement element that corresponds to a property of a commerce item type. ATG supports the search result refinement using the Faceted Search concept. Read more about facted search @  http://en.wikipedia.org/wiki/Faceted_search . Facet can either be ranges or specific values. Each facet is stored in the RefinementRepository as a separate refineElement repository item. Facets are divided into Global and Local facets. Global facets apply to all the categories and local facets only to the category in which they are created. For example Price/Brand can be considered as the facets that are common for all skus and New Release/Coming Soon can be considered as the facets that are specific to Physical Media products like Vidoe/DVD/Blue-ray/Books. We can use the ATG BCC - Merchandising UI to create facets. The Faceting Property depends on the meta-properties defined in the \atg\commerce\search\product-catalog-output-config.xml ( the def...

How to simulate Browser back button

When someone asks how to simulate a back button, they really mean to ask how to create a link that points to the previously visited page. Most browsers tend to keep a list of which websites the user has visited and in what order they have done so. The DOM window object provides access to the browser's history through the history object. Moving backward and forward through the user's history is done using the   back(), forward(), and go() methods of the  history  object. To move backward through history, just do window.history.back() ; This will act exactly like the user clicked on the Back button in their browser toolbar. Find below a sample html code: <html> <head> <script type="text/javascript"> function goBack(){  window.history.back() } </script> </head> <body>    <input type="button" value="Back" onclick="goBack()" /> </body> </html>

ATG - how to prevent Cross-Site attacks using _dynSessConf parameter

Cross-site scripting attacks take advantage of a vulnerability that enables a malicious site to use your browser to submit form requests to another site. In order to protect forms from cross-site attacks in ATG, you can enable form submissions to automatically supply the request parameter _dynSessConf , which identifies the current session through a randomly generated long number. On submission of a form (using dsp:form tag) or activation of a property setting (using dsp:a tag), the request-handling pipeline ( DAFDropletEventServlet ) validates _dynSessConf  against its session confirmation identifier. If it detects a mismatch or missing number, it can block form processing and return an error. To disable this functionality, we could give the following properties (@ /atg/dynamo/Configuration to disable it globally) enforceSessionConfirmation  = false -->  specifies whether the request-handling pipeline requires session confirmation in order to proc...

Basic design decisions for a commerce search setup ( with an ATG Search view)

In this blog I would like to explain the basic set of configuration/design decisions needed to setup an ATG search project. Most of these design decisions are common for all Enterprise search applications. 1. Decide the searchable properties :   This means the properties that the business want the user to search in the ecommerce platform. In ATG search these are configured as the text properties in the product-catalog-output-config.xml ( the definitionFile of the \atg\commerce\search\ProductCatalogOutputConfig). Usually the displayName of product/sku, displayName of department/category/sub-category, skuId, brandName are the properties configured as searchable. 2. Decide the search refinement properties or the faceted properties :   After a user search for a keyword, search refinement is the next step done to filter his results. ATG supports the search refinement using the Faceted Search concept. Read more about facted search @...