Friday, 23 June 2017

Introduction to Filter API

Filters are compontents that you can use and configure to perform some filtering tasks. Filter is used for pre-processing of requests and post-processing of responses. You can have any number of filters for pre-processing of a request and post-processing of a response. Filters are configured in the deployment descriptor of a web application.


How Filters Works?

  • When a request reaches the Web Container, it checks if any filter has URL patterns that matches the requested URL.
  • The Web Container locates the first filter with a matching URL pattern and filter's code is executed.
  • If another filter has a matching URL pattern, its code is then executed. This continues until there are no filters with matching URL patterns left.
  • If no error occurs, the request passes to the target servlet. Hence we know, that the request will be passed to the target servlet only when all the related Filters are successfully executed.
  • The servlet returns the response back to its caller. The last filter that was applied to the request is the first filter applied to the response.
  • At last the response will be passed to the Web Container which passes it to the client.

More about Filter API

Filter API is part of Servlet API. Filter interface is found in the javax.servlet package.
For creating a filter, we must implement Filter interface. Filter interface gives the following life cycle methods for a filter:
  1. void init(FilterConfig filterConfig): invoked by the web container to indicate to a filter that it is being placed into service.
  2. void doFilter(ServletRequest request, ServletResponse response, FilterChain chain): invoked by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.
  3. void destroy(): invoked by the web container to indicate to a filter that it is being taken out of service.

What is FilterChain Interface?

FilterChain object is used to invoke the next filter in the chain, or if the calling filter is the last filter in the chain then the rosource at the end of the chain invoked. The resources at the end of Filter chain can either be a target Servlet(in case of request flow) or the Client(in case of response flow) as described in the diagram above.

Declaring a Filter inside Deployment Descriptor



Example demonstrating Filter usage

In this example we are using Filter to authenticate(check correct username and password). Here index.html will ask username and password from the user, MyFilter will validate the password entered by the user, if the user has entered "1234" as password, then he will be forwarded to first servlet else the index.html will be shown again to the user.
This is exactly what we used to do earlier using two servlet classes earlier, one for validation and the other to Welcome the user. Now we will insert a Filter for validating the user.

index.html
<form method="post" action="first">
    Name:<input type="text" name="user" /><br/>
    Password:<input type="text" name="pass" /><br/>
    <input type="submit" value="submit" />
</form>

web.xml
<web-app..>
    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <servlet-name>first</servlet-name>
    </filter-mapping>
    <servlet>
        <servlet-name>first</servlet-name>
        <servlet-class>first</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>first</servlet-name>
        <url-pattern>/first</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

MyFilter.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class MyFilter implements Filter {
 
    public void init(FilterConfig fc) throws ServletException {}
    
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        PrintWriter out = response.getWriter();
        String pass = request.getParameter("pass");
        if(pass.equals("1234"))
        {
         chain.doFilter(request, response);   
        }
        else
        {
            out.println("You have enter a wrong password");
            RequestDispatcher rs = request.getRequestDispatcher("index.html");
            rs.include(request, response);
        }
    }
   public void destroy() { }
}

first.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class first extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException 
     {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String user = request.getParameter("user");
        out.println("Wellcome "+user);
     }
}

ServletRequestEvent and ServletRequestListener

ServletRequestEvent and ServletRequestListener

ServletRequestEvent class gives notification about lifecycle events for a ServletRequest. The source of the event is the ServletContext of the web application. ServletRequestListener receives the notifications generated by ServletRequestEvent and performs some specified tasks based on them.

Some Importants Methods of ServletRequestListener

MethodsDescription
void requestDestroyed(ServletRequestEvent e)is invoked when request is about to go out of scope of the web application..
void requestInitialized(ServletRequestEvent e)is invoked when request is about to come into scope of the web application.

Example



Hence one can easily implement the ServletRequestListener Interface and provide definitions to the two methods provided by it, requestDestroyed() and requestInitialized().
As the name suggests these methods will be called when request is initialized and when it is destroyed, hence we can use them for various purposes, like variable cleanup when request is destroyed, or performing some initial checks when request is received etc.

HttpSessionEvent and HttpSessionListener

HttpSessionEvent and HttpSessionListener

HttpSessionEvent class gives notifications for changes to sessions within a web application. HttpSessionListener receives notifications of changes to the list of active sessions in a web application and perform some action. HttpSessionListener is used to perform some important tasks when a session is created or destroyed. For example: counting the number of active session.

Some other Session related Listeners

ListenerDescription
HttpSessionActivationListenerLet's you know when a session moves from one Virtual machine to another.
HttpSessionBindingListenerLe's your attribute class object get notified when they are added or removed from session.
HttpSessionAttributeListenerLet's you know when any attribute is added, removed or replaced in a session.

Methods of HttpSessionListener

MethodsDescription
void sessionCreated(HttpSessionEvent e)notification that a session was created.
void sessionDestroyed(HttpSessioEvent e)notification that a session was destroyed.

Example of HttpSessionListener

In this example we will create a session listener that will count the number of active sessions in a web application.

MySessionCounter.java
import javax.servlet.http.*;

public class MySessionCounter implements HttpSessionListener {

    private static int sessionCount; 
    
    public int getActiveSession()
    {
        return sessionCount;
    }
   
    public void sessionCreated(HttpSessionEvent e) 
    {   
        sessionCount++;  
    }

    public void sessionDestroyed(HttpSessionEvent e) 
    {
        sessionCount--;
    }
}

web.xml
<web-app ...>
<listener>
       <listener-class>MySessionCounter</listener-class>
</listener>
</web-app>

What is ServletRequestAttributeEvent

What is ServletRequestAttributeEvent?

ServletRequestAttributeEvent class gives notifications about changes to the attributes of ServletRequestin an application.
This class listens to the notifications and performs some important tasks whenever there is any change to the request attribute.

Some Important Methods of ServletRequestAttributeListener

MethodsDescription
void attributeAdded(ServletRequestAttributeEvent e)notification that a new attribute was added to the servlet request.
void attributeRemoved(ServletRequestAttributeEvent e)notification that an existing attribute was removed from the servlet request.
void attributeReplaced(ServletRequestAttributeEvent e)notification that an attribute was replaced on the servlet request

What is ServletContextAttributeEvent?

ServletContextAttributeEvent class let's you know if an attribute in a web application context has been added, removed or replaced.
Implementation of ServletContextAttributeListener interface, receive notifications of changes to the attribute list on the servlet context of a web application.

Some Important Methods of ServletContextAttributeListener

MethodsDescription
void attributeAdded(ServletContextAttributeEvent e)notification that a new attribute was added to the context.
void attributeRemoved(ServletContextAttributeEvent e)notification that an existing attribute was removed from the context.
void attributeReplaced(ServletContextAttributeEvent e)notification that an attribute was replaced on the context

ServletContextEvent and ServletContextListener

ServletContextEvent and ServletContextListener?

ServletContextEvent class gives notifications about changes to the servlet context of a web application. ServletContextListener receives the notifications about changes to the servlet context and perform some action. ServletContextListener is used to perform important task at the time when context is initialized and destroyed. In short, ServletContextEvent and ServletContextListener works in pair, whenever Servlet COntext changes, ServletContextEvent publishes a notification which is received by ServletContextListener and then, based on that certain tasks are performed by it.

Methods of ServletContextListener Interface

MethodsDescription
void contextDestroyed(ServletContextEvent e)is invoked when the application is destroyed.
void contextInitialized(ServletContextEvent e)is invoked when the application is initialized.

Making and Using a context listener

Context listener is not a servlet or JSP, it's a class that implements ServletContextListener interface and provides definition of contextDestroyed() and contextInitialized().



Example demontrating usage of ServletContextListener


index.html
<a href="Counter">Total Page views</a>

web.xml



For this example we will have to create a table named counter with a column named pageview to save the number of pageviews.
MyListener.java
import java.sql.*;
import javax.servlet.*;

public class MyListener implements ServletContextListener
{
    ServletContext ctx;
    Connection con;
    Statement s;
    PreparedStatement ps;
    ResultSet rs;
    int count;
    
    public void contextInitialized(ServletContextEvent sce) {
    
     try{
        Class.forName("com.mysql.jdbc.Driver");
       con= DriverManager.
               getConnection("jdbc:mysql://localhost:3306/test","user","password");

      s=con.createStatement();
      
      //fetching pageviews value from table counter
      rs=s.executeQuery("select pageview from counter");
        while(rs.next())
        {
            count=rs.getInt(1);
        }
       
       ctx=sce.getServletContext();
       ctx.setAttribute("pcount", count);
      }
      catch(Exception e){ e.printStackTrace(); }  
    }

    public void contextDestroyed(ServletContextEvent sce) {
   
     try
     {
       ctx=sce.getServletContext();
       count=(Integer)ctx.getAttribute("pcount");
       ps=con.prepareStatement("update counter set pcount='"+count+"'");
       ps.executeUpdate(); 
     } 
     catch(Exception e){ e.printStackTrace(); }
    }   
}

Counter.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Counter extends HttpServlet {
   
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        ServletContext ctx = getServletContext();
        Integer count = (Integer)ctx.getAttribute("pcount");
        out.println(count+": pageview");
        ctx.setAttribute("pcount", ++count);      
    }
}

Using Hidden Form Field for Session Management

Using Hidden Form Field for Session Management

Hidden form field can also be used to store session information for a particular client. In case of hidden form field a hidden field is used to store client state. In this case user information is stored in hidden field value and retrieved from another servlet.

Advantages :

  • Does not have to depend on browser whether the cookie is disabled or not.
  • Inserting a simple HTML Input field of type hidden is required. Hence, its easier to implement.

Disadvantage :

  • Extra form submission is required on every page. This is a big overhead.

Example demonstrating usage of Hidden Form Field for Session




Below mentioned files are required for the example:

index.html
<form method="post" action="validate">
  Name:<input type="text" name="user" /><br/>
  Password:<input type="text" name="pass" ><br/>
  <input type="submit" value="submit">
</form>

web.xml
<web-app...>
    
    <servlet>
        <servlet-name>First</servlet-name>
        <servlet-class>First</servlet-class>
    </servlet> 
    <servlet-mapping>
        <servlet-name>First</servlet-name>
        <url-pattern>/First</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>Second</servlet-name>
        <servlet-class>Second</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Second</servlet-name>
        <url-pattern>/Second</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    
</web-app>

First.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class First extends HttpServlet {

  protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        
 //getting value submitted in form from HTML file
        String user = request.getParameter("user");
        
        //creating a new hidden form field
        out.println("<form action='Second'>");
        out.println("<input type='hidden' name='user' value='"+user+"'>");
        out.println("<input type='submit' value='submit' >");
        out.println("</form>");
    }
}

Second.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Second extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        
        //getting parameter from the hidden field
        String user = request.getParameter("user");
        out.println("Welcome "+user);
    }
}

Like we created a hidden field in First Servlet, populated the value of user, and sent it to the Second Servlet, now Second servlet also has the user information. Similarly we will have to keep sending this information, wherever we need this, using hidden fields.

Using URL Rewriting for Session Management

Using URL Rewriting for Session Management

If the client has disabled cookies in the browser then session management using cookie wont work. In that case URL Rewriting can be used as a backup. URL rewriting will always work.
In URL rewriting, a token(parameter) is added at the end of the URL. The token consist of name/value pair seperated by an equal(=) sign.
For Example:


When the User clicks on the URL having parameters, the request goes to the Web Container with extra bit of information at the end of URL. The Web Container will fetch the extra part of the requested URL and use it for session management.
The getParameter() method is used to get the parameter value at the server side.

Example demonstrating usage of URL rewriting

Below mentioned files are required for the example:

index.html
<form method="post" action="validate">
  Name:<input type="text" name="user" /><br/>
  Password:<input type="text" name="pass" ><br/>
  <input type="submit" value="submit">
</form>

web.xml
<web-app...>
    
    <servlet>
        <servlet-name>validate</servlet-name>
        <servlet-class>MyServlet</servlet-class>
    </servlet> 
    <servlet-mapping>
        <servlet-name>validate</servlet-name>
        <url-pattern>/validate</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>First</servlet-name>
        <servlet-class>First</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>First</servlet-name>
        <url-pattern>/First</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    
</web-app>

MyServlet.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class MyServlet extends HttpServlet {

  protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String name = request.getParameter("user");
        String pass = request.getParameter("pass");
        
        if(pass.equals("1234"))
        {
            response.sendRedirect("First?user_name="+name+"");
        }
    }   
}

First.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class First extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String user = request.getParameter("user_name");
        out.println("Welcome "+user);
    }
}

Using Cookies for Session Management

Using Cookies for Session Management

Cookies are small pieces of information that are sent in response from the web server to the client. Cookies are the simplest technique used for storing client state.
Cookies are stored on client's computer. They have a lifespan and are destroyed by the client browser at the end of that lifespan.
Using Cookies for storing client state has one shortcoming though, if the client has turned of COokie saving settings in his browser then, client state can never be saved because the browser will not allow the application to store cookies.

Cookies API

Cookies are created using Cookie class present in Servlet API. Cookies are added to response object using the addCookie() method. This method sends cookie information over the HTTP response stream. getCookies() method is used to access the cookies that are added to response object.



Example demonstrating usage of Cookies



Below mentioned files are required for the example:

index.html
<form method="post" action="validate">
  Name:<input type="text" name="user" /><br/>
  Password:<input type="text" name="pass" ><br/>
  <input type="submit" value="submit">
</form>

web.xml
<web-app...>
    
    <servlet>
        <servlet-name>validate</servlet-name>
        <servlet-class>MyServlet</servlet-class>
    </servlet> 
    <servlet-mapping>
        <servlet-name>validate</servlet-name>
        <url-pattern>/validate</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>First</servlet-name>
        <servlet-class>First</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>First</servlet-name>
        <url-pattern>/First</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    
</web-app>

MyServlet.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class MyServlet extends HttpServlet {

  protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String name = request.getParameter("user");
        String pass = request.getParameter("pass");
        
        if(pass.equals("1234"))
        {
            Cookie ck = new Cookie("username",name);
            response.addCookie(ck);
            response.sendRedirect("First");
        }
    }
}

First.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class First extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        Cookie[] cks = request.getCookies();
        out.println("Welcome "+cks[0].getValue());
    }
}

What is HttpSession

What is HttpSession?

HttpSession object is used to store entire session with a specific client. We can store, retrieve and remove attribute from HttpSession object. Any servlet can have access to HttpSession object throughout the getSession() method of the HttpServletRequest object.

How HttpSession works



  1. On client's first request, the Web Container generates a unique session ID and gives it back to the client with response. This is a temporary session created by web container.
  2. The client sends back the session ID with each request. Making it easier for the web container to identify where the request is coming from.
  3. The Web Container uses this ID, finds the matching session with the ID and associates the session with the request.

HttpSession Interface



Some Important Methods of HttpSession

MethodsDescription
long getCreationTime()returns the time when the session was created, measured in milliseconds since midnight January 1, 1970 GMT.
String getId()returns a string containing the unique identifier assigned to the session.
long getLastAccessedTime()returns the last time the client sent a request associated with the session
int getMaxInactiveInterval()returns the maximum time interval, in seconds.
void invalidate()destroy the session
boolean isNew()returns true if the session is new else false
void setMaxInactiveInterval(int interval)Specifies the time, in seconds,after servlet container will invalidate the session.

Complete Example demonstrating usage of HttpSession

All the files mentioned below are required for the example.
index.html
<form method="post" action="Validate">
  User: <input type="text" name="user" /><br/>
  Password: <input type="text" name="pass" ><br/>
  <input type="submit" value="submit">
</form>

web.xml
<web-app..>
    
    <servlet>
        <servlet-name>Validate</servlet-name>
        <servlet-class>Validate</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>Welcome</servlet-name>
        <servlet-class>Welcome</servlet-class>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>Validate</servlet-name>
        <url-pattern>/Validate</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Welcome</servlet-name>
        <url-pattern>/Welcome</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    
</web-app>

Validate.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Validate extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        
        String name = request.getParameter("user");
        String pass = request.getParameter("pass");
        
        if(pass.equals("1234"))
        {
            //creating a session
            HttpSession session = request.getSession();
            session.setAttribute("user", name);
            response.sendRedirect("Welcome");
        }
    }
}

Welcome.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Welcome extends HttpServlet {
 
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        String user = (String)session.getAttribute("user");
        out.println("Hello "+user);
    }
}

Managing Session in Servlets

Managing Session in Servlets

We all know that HTTP is a stateless protocol. All requests and responses are independent. But sometimes you need to keep track of client's activity across multiple requests. For eg. When a User logs into your website, not matter on which web page he visits after logging in, his credentials will be with the server, until he logs out. So this is managed by creating a session.
Session Management is a mechanism used by the Web container to store session information for a particular user. There are four different techniques used by Servlet application for session management. They are as follows:
  1. Cookies
  2. Hidden form field
  3. URL Rewriting
  4. HttpSession
Session is used to store everything that we can get from the client from all the requests the client makes.




The basic concept behind session is, whenever a user starts using our application, we can save a unique identification information about him, in an object which is available throughout the application, until its destroyed. So wherever the user goes, we will always have his information and we can always manage which user is doing what. Whenever a user wants to exit from your application, destroy the object with his information.

Servlet Filters and Event Listeners

Servlet Filters and Event Listeners
This chapter describes the following servlet features:
Servlet Filters
Servlet filters are used for preprocessing Web application requests and postprocessing responses, as described in the following sections:
Overview of Servlet Filters
When the servlet container calls a method in a servlet on behalf of the client, the HTTP request that the client sent is, by default, passed directly to the servlet. The response that the servlet generates is, by default, passed directly back to the client, with its content unmodified by the container. In this scenario, the servlet must process the request and generate as much of the response as the application requires.
But there are many cases in which some preprocessing of the request for servlets would be useful. In addition, it is sometimes useful to modify the response from a class of servlets. One example is encryption. A servlet, or a group of servlets in an application, may generate response data that is sensitive and should not go out over the network in clear-text form, especially when the connection has been made using a nonsecure protocol such as HTTP. A filter can encrypt the responses. Of course, in this case the client must be able to decrypt the responses.
A common scenario for a filter is one in which you want to apply preprocessing or postprocessing to requests or responses for a group of servlets, not just a single servlet. If you need to modify the request or response for just one servlet, there is no need to create a filter—just do what is required directly in the servlet itself.
Note that filters are not servlets. They do not implement and override HttpServlet methods such as doGet() or doPost(). Rather, a filter implements the methods of the javax.servlet.Filter interface. The methods are:
  • init()
  • destroy()
  • doFilter()
How the Servlet Container Invokes Filters
Figure 3-1 shows how the servlet container invokes filters. On the left is a scenario in which no filters are configured for the servlet being called. On the right, several filters (1, 2, ..., N) have been configured in a chain to be invoked by the container before the servlet is called and after it has responded. The web.xml file specifies which servlets cause the container to invoke the filters.
Figure 3-1 Servlet Invocation with and without Filters

The order in which filters are invoked depends on the order in which they are configured in the web.xml file. The first filter in web.xml is the first one invoked during the request, and the last filter in web.xml is the first one invoked during the response. Note the reverse order during the response.

Note:
Be careful in coordinating any use of multiple filters, in case of possible overlap in functionality or in what the filters are overwriting.

Filtering of Forward or Include Targets
In the OC4J 10.1.2 implementation, when a servlet is filtered, any servlets that are forwarded to or included from the filtered servlet are not filtered by default. You can change this behavior, however, through the following environment setting:
oracle.j2ee.filter.on.dispatch=true

This flag is set to false by default.

Note:
This flag is a temporary mechanism for the current release. Future releases will adhere to version 2.4 of the servlet specification, which directs that servlets that are forwarded to or included from a filtered servlet are not filtered by default. But in compliance with the specification, you can configure this behavior through the web.xml file.

See "Servlet Includes and Forwards" for general information about including and forwarding.
Filter Examples
This section lists and describes three servlet filter examples.
Filter Example 1
This section provides a simple filter example. Any filter must implement the three methods in the javax.servlet.Filter interface or must extend a class that implements them. So the first step is to write a class that implements these methods. This class, which we will call MyGenericFilter, can be extended by other filters.
Generic Filter
Here is the generic filter code. Assume that this generic filter is part of a package com.example.filter and set up a corresponding directory structure.
This is an elementary example of an empty (or "pass-through") filter and could be used as a template.
package com.example.filter;
import javax.servlet.*;

public class MyGenericFilter implements javax.servlet.Filter {
  public FilterConfig filterConfig;                                 //1

  public void doFilter(final ServletRequest request,                //2
                       final ServletResponse response,
                       FilterChain chain)
      throws java.io.IOException, javax.servlet.ServletException {
    chain.doFilter(request,response);                               //3
  }

  public void init(final FilterConfig filterConfig) {               //4
    this.filterConfig = filterConfig;
  }

  public void destroy() {                                           //5
  }
}

Save this code in a file called MyGenericFilter.java in the package directory. The numbered code notes refer to the following:
  1. This code declares a variable to save the filter configuration object.
  2. The doFilter() method contains the code that implements the filter.
  3. In the generic case, just call the filter chain.
  4. The init() method saves the filter configuration in a variable.
  5. The destroy() method can be overridden to accomplish any required finalization.
Filter Code: HelloWorldFilter.java
This filter overrides the doFilter() method of the MyGenericFilter class above. It prints a message on the console when it is called on entrance, then adds a new attribute to the servlet request, then calls the filter chain. In this example there is no other filter in the chain, so the container passes the request directly to the servlet. Enter the following code in a file called HelloWorldFilter.java:
package com.acme.filter;

import javax.servlet.*;

public class HelloWorldFilter extends MyGenericFilter {
  private FilterConfig filterConfig;

  public void doFilter(final ServletRequest request,
                       final ServletResponse response,
                       FilterChain chain)
       throws java.io.IOException, javax.servlet.ServletException  {
    System.out.println("Entering Filter");
    request.setAttribute("hello","Hello World!");
    chain.doFilter(request,response);
    System.out.println("Exiting HelloWorldFilter");
  }
}
JSP Code: filter.jsp
To keep the example simple, the "servlet" to process the filter output is written as a JSP page. Here it is:
<HTML>
<HEAD>
<TITLE>Filter Example 1</TITLE>
</HEAD>
<BODY>
<HR>
<P><%=request.getAttribute("hello")%></P>
<P>Check your console output!</P>
<HR>
</BODY>
</HTML>

The JSP page gets the new request attribute, hello, that the filter added, and prints its value on the console. Put the filter.jsp page in the root directory of the OC4J standalone default Web application, and make sure your console window is visible when you invoke filter.jsp from your browser.
Setting Up Example 1
To test the filter examples in this chapter, use the OC4J standalone default Web application. Configure the filter in the web.xml file in the default Web application /WEB-INF directory (j2ee/home/default-web-app/WEB-INF, by default).
You will need the following entries in the <web-app> element:
  <!-- Filter Example 1 -->
  <filter>
    <filter-name>helloWorld</filter-name>
    <filter-class>com.acme.filter.HelloWorldFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>helloWorld</filter-name>
    <url-pattern>/filter.jsp</url-pattern>
  </filter-mapping>
  <!-- end Filter Example 1 -->

The <filter> element defines the name of the filter and the Java class that implements the filter. The <filter-mapping> element defines the URL pattern that specifies which targets the <filter-name> element should apply to. In this simple example, the filter applies to only one target: the JSP code in filter.jsp.
Running Example 1
Invoke filter.jsp from your Web browser. The console output should look like this:
hostname% Entering Filter
Exiting HelloWorldFilter

The Web browser output is similar to that shown in Figure 3-2, which follows.
Figure 3-2 Example 1 Output
Filter Example 2
You can configure a filter with initialization parameters in the web.xml file. This section provides a filter example that uses the following web.xml entry, which demonstrates a parameterized filter:
  <!-- Filter Example 2 -->
  <filter>
    <filter-name>message</filter-name>
    <filter-class>com.acme.filter.MessageFilter</filter-class>
    <init-param>
      <param-name>message</param-name>
      <param-value>A message for you!</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>message</filter-name>
    <url-pattern>/filter2.jsp</url-pattern>
  </filter-mapping>
  <!-- end Filter Example 2 -->

Here, the filter named message has been configured with an initialization parameter, also called message. The value of the message parameter is "A message for you!"
Filter Code: MessageFilter.java
Following is the code to implement the message filter example. Note that it uses the MyGenericFilter class from "Filter Example 1".
package com.acme.filter;
import javax.servlet.*;

public class MessageFilter extends MyGenericFilter {
  public void doFilter(final ServletRequest request,
                       final ServletResponse response,
                       FilterChain chain)
       throws java.io.IOException, javax.servlet.ServletException {
    System.out.println("Entering MessageFilter");
    String message = filterConfig.getInitParameter("message");
    request.setAttribute("message",message);
    chain.doFilter(request,response);
    System.out.println("Exiting MessageFilter");
  }
}

This filter uses the filterConfig object that was saved in the generic filter. The filterConfig.getInitParameter() method returns the value of the initialization parameter.
JSP Code: filter2.jsp
As in the first example, this example uses a JSP page to implement the "servlet" that tests the filter. The filter named in the <url-pattern> tag above is filter2.jsp. Here is the code, which you can enter into a file filter2.jsp in the OC4J standalone default Web application root directory:
<HTML>
<HEAD>
<TITLE>Lesson 2</TITLE>
</HEAD>
<BODY>
<HR>
<P><%=request.getAttribute("message")%></P>
<P>Check your console output!</P>
<HR>
</BODY>
</HTML>
Running Example 2
Verify that the filter configuration has been entered in the web.xml file, as shown above. Then access the JSP page with your browser. The console output is similar to the following:
Auto-deploying file:/private/tssmith/appserver/default-web-app/ (Assembly had been updated)...
Entering MessageFilter
Exiting MessageFilter

Note the message from the server showing that it redeployed the default Web application after the web.xml file was edited, and note the messages from the filter as it was entered and exited. The Web browser output is similar to that shown in Figure 3-3, which follows.
Figure 3-3 Example 2 Output
Filter Example 3
A particularly useful function for a filter is to manipulate the response to a request. To accomplish this, use the standard javax.servlet.http.HttpServletResponseWrapper class, a custom javax.servlet.ServletOutputStream object, and a filter. To test the filter, you also need a target to be processed by the filter. In this example, the target that is filtered is a JSP page.
Create three new classes to implement this example:
  • FilterServletOutputStream: This class is a new implementation of ServletOutputStream for response wrappers.
  • GenericResponseWrapper: This class is a basic implementation of the response wrapper interface.
  • PrePostFilter: This class implements the filter.
This example uses the HttpServletResponseWrapper class to wrap the response before it is sent to the target. This class is an object that acts as a wrapper for the ServletResponse object (using a Decorator design pattern, as described in software design textbooks). It is used to wrap the real response so that it can be modified after the target of the request has delivered its response.
The HTTP servlet response wrapper developed in this example uses a custom servlet output stream that lets the wrapper manipulate the response data after the servlet (or JSP page, in this example) is finished writing it out. Normally, this cannot be done after the servlet output stream has been closed (essentially, after the servlet has committed it). That is the reason for implementing a filter-specific extension to the ServletOutputStream class in this example.
Output Stream: FilterServletOutputStream.java
The FilterServletOutputStream class is used to manipulate the response of another resource. This class overrides the three write() methods of the standard java.io.OutputStream class.
Here is the code for the new output stream:
package com.acme.filter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class FilterServletOutputStream extends ServletOutputStream {

  private DataOutputStream stream;

  public FilterServletOutputStream(OutputStream output) {
    stream = new DataOutputStream(output);
  }

  public void write(int b) throws IOException  {
    stream.write(b);
  }

  public void write(byte[] b) throws IOException  {
    stream.write(b);
  }

  public void write(byte[] b, int off, int len) throws IOException  {
    stream.write(b,off,len);
  }

}

Save this code in the following directory, under the default Web application root directory (j2ee/home/default-web-app by default), and compile it:
/WEB-INF/classes/com/acme/filter
Servlet Response Wrapper: GenericResponseWrapper.java
To use the custom ServletOutputStream class, implement a class that can act as a response object. This wrapper object is sent back to the client in place of the original response that was generated.
The wrapper must implement some utility methods, such as to retrieve the type and length of its content. The GenericResponseWrapper class accomplishes this:
package com.acme.filter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class GenericResponseWrapper extends HttpServletResponseWrapper {
  private ByteArrayOutputStream output;
  private int contentLength;
  private String contentType;

  public GenericResponseWrapper(HttpServletResponse response) {
    super(response);
    output=new ByteArrayOutputStream();
  }

  public byte[] getData() {
    return output.toByteArray();
  }

  public ServletOutputStream getOutputStream() {
    return new FilterServletOutputStream(output);
  }
 
  public PrintWriter getWriter() {
    return new PrintWriter(getOutputStream(),true);
  }

  public void setContentLength(int length) {
    this.contentLength = length;
    super.setContentLength(length);
  }

  public int getContentLength() {
    return contentLength;
  }

  public void setContentType(String type) {
    this.contentType = type;
    super.setContentType(type);
  }


  public String getContentType() {
    return contentType;
  }
}

Save this code in the following directory, under the default Web application root directory (j2ee/home/default-web-app by default), and compile it:
/WEB-INF/classes/com/acme/filter
Writing the Filter
This filter adds content to the response after that target is invoked. This filter extends the filter from "Generic Filter".
Here is the filter code, PrePostFilter.java:
package com.acme.filter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class PrePostFilter extends MyGenericFilter {

  public void doFilter(final ServletRequest request,
                       final ServletResponse response,
                       FilterChain chain)
       throws IOException, ServletException {
  OutputStream out = response.getOutputStream();
  out.write("<HR>PRE<HR>".getBytes());
  GenericResponseWrapper wrapper =
         new GenericResponseWrapper((HttpServletResponse) response);
  chain.doFilter(request,wrapper);
  out.write(wrapper.getData());
  out.write("<HR>POST<HR>".getBytes());
  out.close();
  }
}

Save this code in the following directory, under the default Web application root directory (j2ee/home/default-web-app by default), and compile it:
/WEB-INF/classes/com/acme/filter

As in the previous examples, create a simple JSP page:
<HTML>
<HEAD>
<TITLE>Filter Example 3</TITLE>
</HEAD>
<BODY>
This is a testpage. You should see<br>
this text when you invoke filter3.jsp, <br>
as well as the additional material added<br>
by the PrePostFilter.
<br>
</BODY>
</HTML>

Save this JSP code in filter3.jsp in the root directory of the default Web application.
Configuring the Filter
Add the following <filter> element to web.xml, after the configuration of the message filter:
  <!-- Filter Example 3 -->
  <filter>
    <filter-name>prePost</filter-name>
    <display-name>prePost</display-name>
    <filter-class>com.acme.filter.PrePostFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>prePost</filter-name>
    <url-pattern>/filter3.jsp</url-pattern>
  </filter-mapping>
  <!-- end Filter Example 3 -->
Running Example 3
Invoke the servlet in your Web browser. You will see a page that looks similar to the page in Figure 3-4, which follows.
Figure 3-4 Example 3 Output
Event Listeners
The servlet specification includes the capability to track key events in your Web applications through event listeners. This functionality allows more efficient resource management and automated processing based on event status. The following sections describe servlet event listeners:
Event Categories and Listener Interfaces
There are two levels of servlet events:
  • Servlet context-level (application-level) event
This event involves resources or state held at the level of the application servlet context object.
  • Session-level event
This event involves resources or state associated with the series of requests from a single user session; that is, associated with the HTTP session object.
Each of these two levels has two event categories:
  • Lifecycle changes
  • Attribute changes
You can create one or more event listener classes for each of the four event categories. A single listener class can monitor multiple event categories.
Create an event listener class by implementing the appropriate interface or interfaces of the javax.servlet package or javax.servlet.http package. Table 3-1 summarizes the four categories and the associated interfaces.
Table 3-1 Event Listener Categories and Interfaces
Event Category
Event Descriptions
Java Interface
Servlet context lifecycle changes
Servlet context creation, at which point the first request can be serviced
Imminent shutdown of the servlet context
javax.servlet. ServletContextListener
Servlet context attribute changes
Addition of servlet context attributes
Removal of servlet context attributes
Replacement of servlet context attributes
javax.servlet. ServletContextAttributeListener
Session lifecycle changes
Session creation
Session invalidation
Session timeout
javax.servlet.http. HttpSessionListener
Session attribute changes
Addition of session attributes
Removal of session attributes
Replacement of session attributes
javax.servlet.http. HttpSessionAttributeListener

Typical Event Listener Scenario
Consider a Web application comprising servlets that access a database. A typical use of the event listener mechanism would be to create a servlet context lifecycle event listener to manage the database connection. This listener may function as follows:
  1. The listener is notified of application startup.
  2. The application logs in to the database and stores the connection object in the servlet context.
  3. Servlets use the database connection to perform SQL operations.
  4. The listener is notified of imminent application shutdown (shutdown of the Web server or removal of the application from the Web server).
  5. Prior to application shutdown, the listener closes the database connection.
Event Listener Declaration and Invocation
Event listeners are declared in the application web.xml deployment descriptor through <listener> elements under the top-level <web-app> element. Each listener has its own <listener> element, with a <listener-class> subelement specifying the class name. Within each event category, event listeners should be specified in the order in which you would like them to be invoked when the application runs.
After the application starts up and before it services the first request, the servlet container creates and registers an instance of each listener class that you have declared. For each event category, listeners are registered in the order in which they are declared. Then, as the application runs, event listeners for each category are invoked in the order of their registration. All listeners remain active until after the last request is serviced for the application.
Upon application shutdown, session event listeners are notified first, in reverse order of their declarations, then application event listeners are notified, in reverse order of their declarations.
Here is an example of event listener declarations, from the Sun Microsystems Java Servlet Specification, Version 2.3:
<web-app>
   <display-name>MyListeningApplication</display-name>
   <listener>
      <listener-class>com.acme.MyConnectionManager</listenerclass>
   </listener>
   <listener>
      <listener-class>com.acme.MyLoggingModule</listener-class>
   </listener>
   <servlet>
      <display-name>RegistrationServlet</display-name>
      ...
   </servlet>
</web-app>

Assume that MyConnectionManager and MyLoggingModule both implement the ServletContextListener interface, and that MyLoggingModule also implements the HttpSessionListener interface.
When the application runs, both listeners are notified of servlet context lifecycle events, and the MyLoggingModule listener is also notified of session lifecycle events. For servlet context lifecycle events, the MyConnectionManager listener is notified first, because of the declaration order.
Event Listener Coding and Deployment Guidelines
Be aware of the following rules and guidelines for event listener classes:
  • In a multithreaded application, attribute changes may occur simultaneously. There is no requirement for the servlet container to synchronize the resulting notifications; the listener classes themselves are responsible for maintaining data integrity in such a situation.
  • Each listener class must have a public zero-argument constructor.
  • Each listener class file must be packaged in the application WAR file, either under /WEB-INF/classes or in a JAR file in /WEB-INF/lib.

Note:
In a distributed environment, the scope of event listeners is one for each deployment descriptor declaration for each JVM. There is no requirement for distributed Web containers to propagate servlet context events or session events to additional JVMs. The servlet specification discusses this.

Event Listener Methods and Related Classes
This section contains event listener methods that are called by the servlet container when a servlet context event or session event occurs. These methods take different types of event objects as input, so these event classes and their methods are also discussed.
ServletContextListener Methods, ServletContextEvent Class
The ServletContextListener interface specifies the following methods:
  • void contextInitialized(ServletContextEvent sce)
The servlet container calls this method to notify the listener that the servlet context has been created and the application is ready to process requests.
  • void contextDestroyed(ServletContextEvent sce)
The servlet container calls this method to notify the listener that the application is about to be shut down.
The servlet container creates a javax.servlet.ServletContextEvent object that is input for calls to ServletContextListener methods. The ServletContextEvent class includes the following method, which your listener can call:
  • ServletContext getServletContext()
Use this method to retrieve the servlet context object that was created or is about to be destroyed, from which you can obtain information as desired. See "Introduction to Servlet Contexts" for information about the javax.servlet.ServletContextinterface.
ServletContextAttributeListener Methods, ServletContextAttributeEvent Class
The ServletContextAttributeListener interface specifies the following methods:
  • void attributeAdded(ServletContextAttributeEvent scae)
The servlet container calls this method to notify the listener that an attribute was added to the servlet context.
  • void attributeRemoved(ServletContextAttributeEvent scae)
The servlet container calls this method to notify the listener that an attribute was removed from the servlet context.
  • void attributeReplaced(ServletContextAttributeEvent scae)
The servlet container calls this method to notify the listener that an attribute was replaced in the servlet context.
The container creates a javax.servlet.ServletContextAttributeEvent object that is input for calls to ServletContextAttributeListener methods. The ServletContextAttributeEvent class includes the following methods, which your listener can call:
  • String getName()
Use method this to get the name of the attribute that was added, removed, or replaced.
  • Object getValue()
Use this method to get the value of the attribute that was added, removed, or replaced. In the case of an attribute that was replaced, this method returns the old value, not the new value.
HttpSessionListener Methods, HttpSessionEvent Class
The HttpSessionListener interface specifies the following methods:
  • void sessionCreated(HttpSessionEvent hse)
The servlet container calls this method to notify the listener that a session was created.
  • void sessionDestroyed(HttpSessionEvent hse)
The servlet container calls this method to notify the listener that a session was destroyed.
The container creates a javax.servlet.http.HttpSessionEvent object that is input for calls to HttpSessionListener methods. The HttpSessionEvent class includes the following method, which your listener can call:
  • HttpSession getSession()
Use this method to retrieve the session object that was created or destroyed, from which you can obtain information as desired. See "Introduction to Servlet Sessions" for information about the javax.servlet.http.HttpSession interface.
HttpSessionAttributeListener Methods, HttpSessionBindingEvent Class
The HttpSessionAttributeListener interface specifies the following methods:
  • void attributeAdded(HttpSessionBindingEvent hsbe)
The servlet container calls this method to notify the listener that an attribute was added to the session.
  • void attributeRemoved(HttpSessionBindingEvent hsbe)
The servlet container calls this method to notify the listener that an attribute was removed from the session.
  • void attributeReplaced(HttpSessionBindingEvent hsbe)
The servlet container calls this method to notify the listener that an attribute was replaced in the session.
The container creates a javax.servlet.http.HttpSessionBindingEvent object that is input for calls to HttpSessionAttributeListener methods. The HttpSessionBindingEvent class includes the following methods, which your listener can call:
  • String getName()
Use this method to get the name of the attribute that was added, removed, or replaced.
  • Object getValue()
Use this method to get the value of the attribute that was added, removed, or replaced. In the case of an attribute that was replaced, this method returns the old value, not the new value.
  • HttpSession getSession()
Use this method to retrieve the session object that had the attribute change.
Event Listener Sample
This section provides code for a sample that uses a servlet context lifecycle and session lifecycle event listener. This includes the following components:
  • SessionLifeCycleEventExample: This is the event listener class, implementing the ServletContextListener and HttpSessionListener interfaces.
  • SessionCreateServlet: This servlet creates an HTTP session.
  • SessionDestroyServlet: This servlet destroys an HTTP session.
  • index.jsp: This is the application welcome page (the user interface), from which you can invoke SessionCreateServlet or SessionDestroyServlet.
  • web.xml: This is the deployment descriptor, in which the servlets and listener class are declared.
To download and run this application, refer to the Use Servlet Lifecycle Events example at the following link:

(These examples were written for older versions of OC4J, but the functionality is similar for the 10.1.2 implementation.)
You must be a member of the Oracle Technology Network, but memberships are free of charge.
Welcome Page: index.jsp
Here is the welcome page, the user interface that enables you to invoke the session-creation servlet by clicking the Create New Session link, or to invoke the session-destruction servlet by clicking the Destroy Current Session link.
<%@page session="false" %>
<H2>OC4J - HttpSession Event Listeners </H2>
<P>
This example demonstrates the use of the HttpSession Event and Listener that is
new with the Java Servlet 2.3 API. 
</P>
<P>
[<a href="servlet/SessionCreateServlet">Create New Session</A>] &nbsp;
[<a href="servlet/SessionDestroyServlet">Destroy Current Session</A>]
</P>
<P>
Click the Create link above to start a new HttpSession. An HttpSession
listener has been configured for this application. The servler container
will send an event to this listener when a new session is created or
destroyed. The output from the event listener will be visible in the
console window from where OC4J was started.
</P>

Note:
No new session object is created if you click the Create New Session link again after having already created a session from the same client, unless the session has reached a timeout limit or you have explicitly destroyed it in the meantime.

Deployment Descriptor: web.xml
The servlets and the event listener are declared in the web.xml file. This results in SessionLifeCycleEventExample being instantiated and registered upon application startup. Because of this, the servlet container automatically calls its methods, as appropriate, upon the occurrence of servlet context or session lifecycle events. Here are the web.xml entries:
<web-app>
   <listener>
      <listener-class>SessionLifeCycleEventExample</listener-class>
   </listener>
   <servlet>
      <servlet-name>sessioncreate</servlet-name>
      <servlet-class>SessionCreateServlet</servlet-class>
   </servlet>
   <servlet>
      <servlet-name>sessiondestroy</servlet-name>
      <servlet-class>SessionDestroyServlet</servlet-class>
   </servlet>
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
</web-app>
Listener Class: SessionLifeCycleEventExample
This section shows the listener class. Its sessionCreated() method is called by the servlet container when an HTTP session is created, which occurs when you click the Create New Session link in index.jsp. When sessionCreated() is called, it calls the log() method to print a "CREATE" message indicating the ID of the new session.
The sessionDestroyed() method is called when the HTTP session is destroyed, which occurs when you click the Destroy Current Session link. When sessionDestroyed() is called, it calls the log() method to print a "DESTROY" message indicating the ID and duration of the terminated session.
import javax.servlet.http.*;
import javax.servlet.*;

public class SessionLifeCycleEventExample
   implements ServletContextListener, HttpSessionListener
{
   /* A listener class must have a zero-argument constructor: */
   public SessionLifeCycleEventExample()
   {
   }

   ServletContext servletContext;

   /* Methods from the ServletContextListener */
   public void contextInitialized(ServletContextEvent sce)
   {
      servletContext = sce.getServletContext();
   }

   public void contextDestroyed(ServletContextEvent sce)
   {
   }

   /* Methods for the HttpSessionListener */
   public void sessionCreated(HttpSessionEvent hse)
   {
      log("CREATE",hse);
   }
   public void sessionDestroyed(HttpSessionEvent hse)
   {

         HttpSession _session = hse.getSession();
         long _start = _session.getCreationTime();
         long _end = _session.getLastAccessedTime();
         String _counter = (String)_session.getAttribute("counter");
         log("DESTROY, Session Duration:"
                   + (_end - _start) + "(ms) Counter:" + _counter, hse);
   }
  
   protected void log(String msg, HttpSessionEvent hse)
   {
      String _ID = hse.getSession().getId();
      log("SessionID:" + _ID + "    " + msg);
   }
  
   protected void log(String msg)
   {
      System.out.println("[" + getClass().getName() + "] " + msg);
   }
}
Session Creation Servlet: SessionCreateServlet.java
This servlet is invoked when you click the Create New Session link in index.jsp. Its invocation results in the servlet container creating a request object and associated session object. Creation of the session object results in the servlet container calling the sessionCreated() method of the event listener class.
import java.io.*;
import java.util.Enumeration;
import java.util.Date;

import javax.servlet.*;
import javax.servlet.http.*;


public class SessionCreateServlet extends HttpServlet {

    public void doGet (HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException
      {
         //Get the session object
         HttpSession session = req.getSession(true);
       
        // set content type and other response header fields first
        res.setContentType("text/html");

        // then write the data of the response
        PrintWriter out = res.getWriter();
     
        String _sval = (String)session.getAttribute("counter");
        int _counter=1;
    
        if(_sval!=null)
        {
           _counter=Integer.parseInt(_sval);
           _counter++;
      }
  
      
      session.setAttribute("counter",String.valueOf(_counter));

      out.println("<HEAD><TITLE> " + "Session Created Successfully ..
         Look at OC4J Console to see whether the HttpSessionEvent invoked "
         + "</TITLE></HEAD><BODY>");
      out.println("<P>[<A HREF=\"SessionCreateServlet\">Reload</A>]&nbsp;");  
      out.println("[<A HREF=\"SessionDestroyServlet\">Destroy Session</A>]");  
      out.println("<h2>Session created Successfully</h2>");
      out.println("Look at the OC4J Console to see whether the HttpSessionEvent
                  was invoked");
      out.println("<h3>Session Data:</h3>");
      out.println("New Session: " + session.isNew());
      out.println("<br>Session ID: " + session.getId());
      out.println("<br>Creation Time: " + new Date(session.getCreationTime()));
      out.println("<br>Last Accessed Time: " +
                   new Date(session.getLastAccessedTime()));
      out.println("<BR>Number of Accesses: " + session.getAttribute("counter"));
     
   }
}
Session Destruction Servlet: SessionDestroyServlet.java
This servlet is invoked when you click the Destroy Current Session link in index.jsp. Its invocation results in a call to the invalidate() method of the session object. This, in turn, results in the servlet container calling the sessionDestroyed() method of the event listener class.
import java.io.*;
import java.util.Enumeration;

import javax.servlet.*;
import javax.servlet.http.*;

public class SessionDestroyServlet extends HttpServlet {

    public void doGet (HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException
      {
         //Get the session object
         HttpSession session = req.getSession(true);
         // Invalidate Session
         session.invalidate();

         // set content type and other response header fields first
         res.setContentType("text/html");

         // then write the data of the response
         PrintWriter out = res.getWriter();

         out.println("<HEAD><TITLE> " + "Session Destroyed Successfully ..
           Look at OC4J Console to see whether the HttpSessionEvent invoked "
           + "</TITLE></HEAD><BODY>");
         out.println("<P>[<A HREF=\"../index.jsp\">Restart</A>]");
         out.println("<h2> Session Destroyed Successfully</h2>");
         out.println("Look at the OC4J Console to see whether the
                      HttpSessionEvent was invoked");
         out.close();
   }
}



Access attributes in component

NOTE: To access an attribute in a  component , use expressions as  {! v.<Attribute Name>} . ----------------------------------------...