[ Team LiB ] Previous Section Next Section

Recipe 16.2 Setting ServletContext Attributes in JSPs

Problem

You want to store an object attribute in the ServletContext using a JSP.

Solution

Use the JSTL c:set tag to bind an object to application scope. The JSTL uses the application implicit object to represent the ServletContext, which is also the scope used for the object attributes discussed in the previous recipe.

Discussion

JSP developers can use the JSTL core tags and the jsp:useBean standard action to implement the same functionality as the servlet in Recipe 16.1. Like the program in that recipe, the upcoming JSP stores in the ServletContext an object attribute that contains a java.util.Map type. The Map stores key/value pairs that are accessed by other servlets or JSPs in the same context.

Here are the steps to bind an attribute to the ServletContext using a JSP:

  1. Create the Java class that you will instantiate and bind to the ServletContext.

  2. Place the Java class in the WEB-INF/classes directory, including any package-related directories (if the class is named com.jspservletcookbook.ContextObject then place the class in WEB-INF/classes/com/jspservletcookbook), or in WEB-INF/lib if the class is stored in a JAR file.

  3. Create the JSP that will bind the object attribute to the ServletContext. Store the JSP in the web application's top-level directory.

  4. If the web container does not already provide the JSTL-related components, include them in WEB-INF/lib (see Chapter 23) so that the JSP can use these tag libraries.

First I show the object attribute that the JSP binds to the ServletContext. Example 16-3 is the same Java class as Example 16-1, except for the getMap( ) method, which returns the Map type that this object uses to store information. I added this method to make the Map available to the c:set core tag (see Example 16-4). Because the two code samples are exactly the same except for the getMap( ) method, Example 16-3 has been abbreviated to show just the creation of the synchronized map and its getter method (see Example 16-1 for the other parts of the class).

Example 16-3. The object attribute bound to the ServletContext by a JSP
package com.jspservletcookbook;           

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;


public class ContextObject  {

    private Map map;

  public ContextObject( ){

      map = Collections.synchronizedMap(new HashMap( ));
  }

  public Map getMap( ){

      return map;

  }
// see Example 16-1 for the other parts of the class
}

Example 16-4 does the work of creating an instance of the object attribute and then binding the attribute to the ServletContext. The code creates the ContextObj instance (which is stored in the ServletContext) with the jsp:useBean standard action. Then the c:set JSTL core tag stores this object in application scope, which is an alias for the ServletContext. The ContextObj class stores information with a Map type that it contains. This code in Example 16-4 stores data in the ServletContext attribute:

<c:set target=
    "${applicationScope[\"com.jspservletcookbook.ContextObject\"].map}"
        value="${date}" property="${pageContext.request.remoteAddr}"/>

The value of the target attribute has the effect of calling getMap( ) on the ContextObj object. The code then creates a new key-value pair in the Map, consisting of the remote IP address of the client making the request (the key) and the current date (the value). I chose this information at random to demonstrate how to store pieces of data in a ServletContext attribute using the JSTL and JSPs. Your own code may store data of practical value to your application such as a customer's unique ID and the item that he is purchasing.

Example 16-4. The contextBind.jsp file
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

<html>
<head><title>Context binding JSP</title></head>
<body>
<h2>Here is the bound ContextObject</h2>

//create an instance of ContextObject; store it as a Page scoped attribute
<jsp:useBean id="contextObj" class=
    "com.jspservletcookbook.ContextObject" />

//create an instance of Date; store it as a Page scoped attribute
<jsp:useBean id="date" class="java.util.Date" />

//bind the object to the ServletContext represented by the 
//'application' implicit object
<c:set var=
    "com.jspservletcookbook.ContextObject" value="${contextObj}" scope=
       "application" />

//create a new key/value pair in the bound object's Map
<c:set target=
    "${applicationScope[\"com.jspservletcookbook.ContextObject\"].map}"
        value="${date}" property="${pageContext.request.remoteAddr}"/>

</body>
</html>

After looking at this code, you may wonder why the ContextObject variable is effectively named twice, once by jsp:useBean when it creates the object (giving the object an id or name contextObj) and again by c:set when it binds the object to the ServletContext (and creating the name com.jspservletcookbook.ContextObject).

By convention, you should name the attribute after its fully qualified class name. However, you cannot use this format with jsp:useBean, because this action creates a Java variable in the underlying servlet. The Java variable is named contextObj.

The JSP container creates a servlet behind the scenes to implement each JSP page.


You cannot include period (.) characters when naming Java variables, so the code renames the object in c:set's var attribute when the object is bound to the ServletContext.

See Also

Chapter 23 on using the JSTL; Recipe 16.1 on setting ServletContext attributes in servlets; Recipe 16.4 on accessing or removing a ServletContext attribute in a JSP; Recipe 16.5-Recipe 16.8 on handling session attributes in servlets and JSPs; Recipe 16.9-Recipe 16.12 on handling request attributes in servlets and JSPs; Recipe 14.5 on using a ServletContext event listener; the Javadoc for javax.servlet.ServletContextAttributeListener: http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletContextAttributeListener.html.

    [ Team LiB ] Previous Section Next Section